TransactionScope-事务WCF和并行/多线程

时间:2019-09-24 18:21:15

标签: c# .net wcf transactionscope

我正在寻找项目中的一个错误,有时我们会 看到数据被保存到数据库中,即使发生异常并且所有内容都应回滚。我有asked about it here before,发现如果我在创建新的@@trancount之后立即在数据库中查询TransactionScope,结果得到0,则没有“有效”交易。它以某种方式被另一个线程中止/回滚。

我用来复制的代码非常简单:

我在Paralell.For中多次调用此方法

void Handle()
{
    try
    {
        using (var transaction = new TransactionScope(TransactionScopeOption.Required)
        {
            // Getting @@trancount right here enables us verify whether we have a valid transaction.

            WriteImportantBusinessDataToDatabase("This will sometimes be committed even if the WCF call below fails!");

            // Making a transactional WCF call
            var serviceClient = new Service1Client("WSHttpBinding_IService1");
            serviceClient.DoWork(); // We get an exception here

            WriteImportantBusinessDataToDatabase("We never reach this location");

            transaction.Complete();
        }
    }
    catch (Exception e)
    {
        Logger.Error(e, "Something failed. {message}", e.Message);
    }
}

WCF服务是事务性的,TransactionFlowOption.Mandatory

[ServiceContract]
public interface IService1
{
    [OperationContract]
    [TransactionFlow(TransactionFlowOption.Mandatory)]
    void DoWork();
}

[ServiceBehavior]
public class Service1 : IService1
{
    [OperationBehavior(TransactionScopeRequired = true)]
    public void DoWork()
    {
        throw new Exception();
    }
}
在创建新的@@trancount之后,

1应该是TransactionScope。但有时候  @@trancount0,在极少数情况下是2。无论System.Transactions.Transaction.Current.TransactionInformation.Status是什么,Active属性始终为@@trancount。将插入数据库执行得很好。发生问题,然后通过WCF调用将本地事务提升为分布式事务。然后,我们得到一个异常消息:“交易已中止。”

方法名称Handle正确表明这确实是一个NServiceBus处理程序,日夜处理数十万条消息。仅当WCF调用的另一端存在问题时,我们才会出现此不一致问题。

可以找到此设置的可运行版本on my GitHub

我已将所有.Net框架版本从4.5.1改为4.8的问题。它们都产生相同的结果。有人能解释这里发生了什么吗?

1 个答案:

答案 0 :(得分:0)

这是由.Net的连接共享机制中的某个错误引起的。该错误在4.5.1和4.8之间的所有.Net Framework版本以及新的System.Data.SqlClient package上都已复制。

一个issue has been added to the System.Data.SqlClient repository