事务范围内的 NLog 导致事务无效

本文关键字:事务 无效 NLog 范围内 | 更新日期: 2023-09-27 18:34:56

我在生产环境中遇到了一个问题,我没有在本地获得。

我正在事务范围内运行一些 LINQ to SQL 代码,如下所示:

        using (var scope = new TransactionScope())
        {
            uploadRepository.SubmitChanges();
            result = SubmitFileResult.Succeed();
            ScanForNewData(upload);
            scope.Complete();
        }

ScanForNewData(( 调用 GetSubmittedData((。如果在 GetSubmitted(( 中发生异常,我们使用 Nlog 将错误写入文件、数据库并发送电子邮件:

        catch (Exception ex)
        {
            //MT - having to comment this out beause it is causing a problem with transactions on theproduction server
            logger.ErrorException(String.Format("Error reading txt file {0} into correct format", upload.DocumentStore.FileName), ex);
            return new UploadGetSubmittedDataResult { Exception = ex, Success = false, Message = String.Format("Error reading txt file {0} into correct format", upload.DocumentStore.FileName) };
        }

在ScanForNewData中,我们调用存储库。提交更改((。这会导致:

该操作对事务的状态无效。System.Transactions.TransactionException TransactionException System.Transactions.TransactionException:该操作对事务的状态无效。

我想出的最好的主意是,在生产环境中,此代码在 Web 服务器上运行并调用单独的数据库服务器。DataContext 和 Nlog 都具有相同的连接字符串配置和 Sql 用户,但可能是因为服务器是远程的(而本地我使用的是集成安全性(,发生了一些奇怪的事情。

知道在这种情况下交易会发生什么吗?

更新 - 我刚刚在本地与SQL用户一起尝试过,它仍然可以正常工作。一定与生产设置有关...

另一个更新 - 我撒谎。在开发操作中,永远不会写入Nlog数据库记录,发送电子邮件,并且不会发生TransactionException。

事务范围内的 NLog 导致事务无效

如果没有异常的完整堆栈跟踪,很难猜测问题是什么,它可能取决于多种因素。

例如,我假设 NLog 打开了一个与数据库的新连接,这可能会导致事务被提升为分布式事务,并且分布式事务处理协调器将启动。这可能会导致应用程序在生产和本地的行为之间出现不对称。

您可能会在其中执行某些操作来破坏事务,例如某些未经处理的异常或非法访问某些数据。

提供完整的堆栈跟踪和更多涉及的代码,以进行更深入的分析。

不知道 TransactionException 的内部异常是什么,这将很难解决,但这里有一个想法:

如果重构代码以使日志记录在事务范围周围的使用块结束后进行日志记录,则可能会避免遇到的问题,因为事务范围将结束,DTC 将回滚事务。

我过去在处理交易时使用并看到过这种模式(直到交易结束并回滚后才记录(,并且效果很好。

始终建议在单独的数据库上进行日志记录,以避免此类问题。如果这样做,也可以避免此问题。

看看这个。似乎是 Nlog 的错误。

https://groups.google.com/forum/#!msg/nlog-users/I5UR-bISlTA/6RPtOZhR4NoJ

建议的解决方案是使用异步目标进行 Db 日志记录。