为什么我突然收到这个错误?

 ly 发布于 2023-01-09 11:12

所以我有一个WCF服务,里面有一个Process()方法.此方法从一个表中读取字节数组(文件),并基本上将该文件中的数据放入多个表中.它只是遍历每一行.它在生产环境中工作了一个月以来一直很好.现在突然间,它间歇地抛出这个错误:

System.InvalidOperationException:与当前连接关联的事务已完成但尚未处理.必须先处理事务,然后才能使用连接执行SQL语句.

可能有所帮助的东西:大约2周前,我们更换了生产网络和数据库服务器.我们搬家后,这个错误一直在呕吐.当我们在旧服务器上时,我从未遇到过这个问题.但问题是,这个错误在前9-10天没有发生.现在它突然间歇地发生了.我已经上传了大文件(1k-2.5k行)并且它们工作正常,并且这个错误会引发更小的200行文件!并且服务有时会完美地处理相同的文件.

代码片段:(它更大,但重复类似的操作)

using (var scope = new TransactionScope())
{
    // loop through each row/invoice
    foreach (var row in Rows)
    {
        Invoice invoice = (Invoice)CreateObjectWithConstantData(typeof(Invoice), doc, applicationName);
        invoice = (Invoice)FillObjectWithUserData(invoice, row, -1, -1, string.Empty);
        invoice.InvoiceNumber = InvoiceDBImpl.SaveInvoice(invoice, processFileRequest.RunId);

        if (invoice.InvoiceNumber == Guid.Empty)
        {
            throw new DataAccessException(string.Format(Messages.ErrorSavingInvoice, invoice.ReceiptId, invoice.ProductID));
        }
    }
}

堆栈跟踪之一:

   at System.Data.SqlClient.TdsParser.TdsExecuteRPC(_SqlRPC[] rpcArray, Int32 timeout, Boolean inSchema, SqlNotificationRequest notificationRequest, TdsParserStateObject stateObj, Boolean isCommandProc)
   at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
   at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe)
   at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
   at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
   at System.Data.Linq.SqlClient.SqlProvider.Execute(Expression query, QueryInfo queryInfo, IObjectReaderFactory factory, Object[] parentArgs, Object[] userArgs, ICompiledSubQuery[] subQueries, Object lastResult)
   at System.Data.Linq.SqlClient.SqlProvider.ExecuteAll(Expression query, QueryInfo[] queryInfos, IObjectReaderFactory factory, Object[] userArguments, ICompiledSubQuery[] subQueries)
   at System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider.Execute(Expression query)
   at System.Data.Linq.DataContext.ExecuteMethodCall(Object instance, MethodInfo methodInfo, Object[] parameters)
   at Tavisca.TramsFileService.DataAccess.TramsDBDataContext.SaveTramsPayment(Nullable`1 paymentDate, String paymentType, Nullable`1 totalAmount, String bankAccount, String paymentMethod, String branch, String remarks, String creditCardLast4, String payeeName, String profileNumber, Nullable`1& paymentId)
   at Tavisca.TramsFileService.DataAccess.PaymentDBImpl.<>c__DisplayClass1.b__0(TramsDBDataContext dc)
   at Tavisca.TramsFileService.DataAccess.SystemDataContext.PerformOperation(Action`1 action)
   at Tavisca.TramsFileService.DataAccess.PaymentDBImpl.SavePayment(Payment payment)
   at Tavisca.TramsFileService.Core.TramsFileController.ProcessFile(ProcessFileRQ processFileRequest)
   at Tavisca.TramsFileService.ServiceImplementation.TramsFileServiceImpl.ProcessFile(ProcessFileRQ processFileRequest)

我经历了一些链接:

    链接1

    链接2

    链接3

他们都建议在machine.config上增加TimeOut,但我不确定为什么它有时会起作用而在其他时候不起作用.这不应该一致吗?

2 个回答
  • 查看此连接文章,显示.NET ADO库中的问题.

    http://connect.microsoft.com/VisualStudio/feedback/details/266095/transactionscope-timeout-issue-with-sqlconnection-and-ltm-some-operations-are-not-rolled-back

    它与必须在客户端(而不是SQL Server)设置的超时有关.

    第一个事务超时但第二个事务抛出错误消息.

    您使用的是.NET 4.0框架吗?

    这是一篇关于如何在C#代码中设置超时的文章.

    http://paulklinker.blogspot.com/2011/08/transaction-timeouts-in-c.html

    2023-01-09 11:14 回答
  • 首先,我建议scope.Complete();在结尾处添加TransactionScope:

    using (var scope = new TransactionScope())
    {
         //Your stuff goes here
    
         scope.Complete();
    }
    

    必须使用.Complete()函数在最后一行提交任何事务.

    其次,如果增加TimeOutmachine.config作品中,有在做任何伤害,因为长文件显然需要更多的时间.

    第三,确保内部调用的任何其他组件TransactionScope都适用于所有正面和负面场景.通过堆栈跟踪,特别是用例似乎有些破坏了内部功能Tavisca.TramsFileService.ServiceImplementation.TramsFileServiceImpl.ProcessFile(ProcessFileRQ processFileRequest)

    还要确保内部任何底层调用是否使用了某个存储过程,TransactionScope然后还可能导致存储过程中的任何失败事务TransactionScope.

    还有一件事,抛出的异常也可能是合法的,因为你手动抛出异常,invoice.InvoiceNumber == Guid.Empty但如果它被处理/捕获或者只是传递给上层,则不提及它.

    但首先尝试添加scope.Complete();,这可能是根本原因.

    2023-01-09 11:17 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有