我正在寻找项目中的一个错误,有时我们会 看到数据被保存到数据库中,即使发生异常并且所有内容都应回滚。我有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
。但有时候
@@trancount
是0
,在极少数情况下是2
。无论System.Transactions.Transaction.Current.TransactionInformation.Status
是什么,Active
属性始终为@@trancount
。将插入数据库执行得很好。发生问题,然后通过WCF调用将本地事务提升为分布式事务。然后,我们得到一个异常消息:“交易已中止。”
方法名称Handle
正确表明这确实是一个NServiceBus处理程序,日夜处理数十万条消息。仅当WCF调用的另一端存在问题时,我们才会出现此不一致问题。
可以找到此设置的可运行版本on my GitHub。
我已将所有.Net框架版本从4.5.1改为4.8的问题。它们都产生相同的结果。有人能解释这里发生了什么吗?
答案 0 :(得分:0)
这是由.Net的连接共享机制中的某个错误引起的。该错误在4.5.1和4.8之间的所有.Net Framework版本以及新的System.Data.SqlClient package上都已复制。
一个issue has been added to the System.Data.SqlClient repository。