【发布时间】:2015-08-12 20:00:49
【问题描述】:
首先,我读过这个类似的问题:Nested/Child TransactionScope Rollback 但答案没有提供解决方案,我们的问题略有不同。
基本上,我有一个使用事务范围的数据库集成测试(实际上,范围是在抽象类的设置/拆卸中管理的)
[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;
}
}
所以理论上,MyMethod 只有在 isCheck 为 true 时才会提交其更改,但无论该事务是否提交,当方法被测试时,它都会被回滚。
除非 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 组合无济于事。
【问题讨论】:
标签: c# sql-server transactions integration-testing transactionscope