为什么我突然收到这个错误? [英] Why am I getting this error suddenly?

查看:35
本文介绍了为什么我突然收到这个错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

So I have a WCF service, inside which there's a Process() method. This method reads a byte array (a file) from one table, and basically puts that data from that file into multiple tables. It just iterates through each row. It was working fine since a month in the Production environment. Now all of a sudden, it throws this error intermittently:

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

System.InvalidOperationException: The transaction associated with the current connection has completed but has not been disposed. The transaction must be disposed before the connection can be used to execute SQL statements.

可能有帮助的东西:大约 2 周前,我们更换了 Production web &数据库服务器.这个错误一直在我们搬家后才出现.当我们在旧服务器上时,我从未遇到过这个问题.但问题是,这个错误并没有在前 9-10 天内发生.现在它突然和间歇性地发生.我已经上传了大文件(1k-2.5k 行)并且它们运行良好,对于具有 200 行的小得多的文件,会出现此错误!有时服务会完美地处理同一个文件.

Something which might help: About 2 weeks ago, we changed out Production web & DB servers. This error has been throwing up only after we moved. I have never encountered this problem when we were on the Old Servers. But the thing is, this error didn't occur in the first 9-10 days. Now it's happening suddenly and intermittently. I've uploaded large files (1k-2.5k rows) and they have worked fine, and this error throws up for much smaller files which have 200 rows! And the Service processes the same file perfectly sometimes.

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

Code snippet: (it's much larger, but similar operations are repeated)

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.<SavePayment>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. 链接1
  2. 链接 2
  3. 链接 3

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

They all suggest increasing the TimeOut on the machine.config, but I'm not sure why it works sometimes and does not work the other times. Shouldn't this be consistent?

推荐答案

首先我会建议在 末尾添加 scope.Complete();TransactionScope 喜欢:

First of all I will suggest adding scope.Complete(); at end of TransactionScope like :

using (var scope = new TransactionScope())
{
     //Your stuff goes here

     scope.Complete();
}

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

Any transaction must be committed at last line using .Complete() function.

其次如果增加 machine.config 上的 TimeOut 有效,这样做没有坏处,因为长文件显然需要更多时间.

Secondly if increasing the TimeOut on the machine.config works, there is no harm in doing it, since long file obviously needs more time.

第三确保在 TransactionScope 中调用的任何其他组件都适用于所有积极的 &负面情景.通过堆栈跟踪,似乎在特定用例中有些正在破坏函数 Tavisca.TramsFileService.ServiceImplementation.TramsFileServiceImpl.ProcessFile(ProcessFileRQ processFileRequest)

Thirdly make sure any other component called inside TransactionScope are working for all positive & negative scenarios. By stacktrace, it seems in particular use case some is breaking inside function Tavisca.TramsFileService.ServiceImplementation.TramsFileServiceImpl.ProcessFile(ProcessFileRQ processFileRequest)

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

Also make sure if some stored procedure is used by any underlying call inside TransactionScope then any failed transaction inside stored procedure can also result TransactionScope.

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

One more thing, exception thrown could be legitimate one also since you are throwing exception manually when invoice.InvoiceNumber == Guid.Empty but its not mentioned if it is handled/ catched or just passed to upper layers.

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

But first of all try adding scope.Complete();, this alone could be root cause.

这篇关于为什么我突然收到这个错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆