C#回滚外部TransactionScope而不管嵌套的TransactionScopes中发生了什么
本文关键字:TransactionScopes 发生了 什么 嵌套 不管 外部 TransactionScope | 更新日期: 2023-09-27 18:07:40
首先,我读过这个类似的问题:嵌套/子事务范围回滚,但答案没有提供解决方案,我们的问题略有不同。
基本上,我有一个数据库集成测试,它使用事务作用域(实际上,作用域是在抽象类中的设置/拆卸中管理的(
[Test]
public void MyTest()
{
using(var outerScope = new TransactionScope())
{
Assert.True(_myService.MyMethod());
var values = _myService.AnotherMethod();
}
}
MyService.MyMethod也使用TransactionScope
public bool MyMethod()
{
using(var innerScope = new TransactionScope())
using(var con = conFact.GetOpenConnection())
{
var cmd = con.CreateCommand();
//set up and execute command
if (isCheck) scope.Complete();
return isCheck;
}
}
因此,理论上,只有当isCheck为true时,MyMethod才会提交其更改,但无论该事务是否提交,当测试该方法时,它都会被回滚。
除非isCheck为false,否则它会按预期工作,在这种情况下,我会得到以下异常:System.Transactions.TransactionException : The operation is not valid for the state of the transaction.
我认为这里发生的事情是,由于innerScope使用了TransactionScopeOption.Required,它加入了outerScope中使用的事务。当isCheck为false时,一旦innerScope被释放,outerScope也会被释放(这是我不希望发生的!(所以当我在调用MyMethod后试图获得另一个连接时,outerScope已经被释放。
或者,如果我指定TransactionOption.RequiresNew,我会得到这个异常:System.Data.SqlClient.SqlException : Timeout expired.
我曾尝试使用具有指定保存点的SqlTransaction,以及TransactionOption的不同组合,但均无效。
没有嵌套事务这回事。您可以嵌套作用域,但嵌套作用域所做的只是附加已经运行的事务。您不能独立于其他作用域来处理内部作用域(当然,RequiresNew只是创建一个独立事务(。
System.Transactions
中不存在所需的功能。
保存点是创建看起来像嵌套事务的东西的唯一方法。但是,SQL Server很容易由于任意原因而终止整个事务。哪些错误回滚语句,哪些错误回滚事务,这是不可预测的。(是的,这毫无意义。(