首先,我已经阅读了这个类似的问题:Nested/Child TransactionScope Rollback但答案并没有提供解决方案,我们的问题略有不同。
基本上,我有一个使用事务范围的数据库集成测试(实际上,范围是在一个抽象类中的setup / teardown中管理)
[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的不同组合无济于事。
答案 0 :(得分:2)
没有嵌套交易这样的东西。您可以嵌套作用域,但嵌套作用域所做的只是附加已在运行的事务。您不能独立于其他范围处理内部范围(当然除了RequiresNew,它只是创建一个独立的事务)。
IE11
中不存在您想要的功能。
保存点是创建看起来像嵌套事务的东西的唯一方法。但是,SQL Server很容易因任意原因而终止您的整个事务。什么错误回滚语句以及哪些错误回滚事务是不可预测的。 (是的,这没有任何意义。)