1 transactions transactionscope system.transactions sql-server-2008
我正在测试看嵌套事务是如何工作的,并发现了这种令人不安和意外的行为.
using(TransactionScope otx = new TransactionScope())
using(SqlConnection conn1 = new SqlConnection("Server=S;Database=DB;Trusted_Connection=yes"))
using(SqlCommand cmd1 = conn1.CreateCommand())
{
conn1.Open();
cmd1.CommandType = CommandType.Text;
cmd1.CommandText = "INSERT INTO FP.ACLs (ChangeToken,ACL) VALUES (1,0x)";
cmd1.ExecuteNonQuery();
using(TransactionScope itx = new TransactionScope(TransactionScopeOption.RequiresNew))
using(SqlConnection conn2 = new SqlConnection("Server=S;Database=DB;Trusted_Connection=yes"))
using(SqlCommand cmd2 = conn1.CreateCommand())
{
conn2.Open();
cmd2.CommandType = CommandType.Text;
cmd2.CommandText = "INSERT INTO FP.ACLs (ChangeToken,ACL) VALUES (2,0x)";
cmd2.ExecuteNonQuery();
// we don't commit the inner transaction
}
otx.Complete(); // nonetheless, the inner transaction gets committed here and two rows appear in the database!
}
Run Code Online (Sandbox Code Playgroud)
我看到了另一个问题,但解决方案并不适用.
如果我没有指定TransactionScopeOption.RequiresNew(即我不使用嵌套事务,只是嵌套作用域),则在内部作用域未完成时回滚整个事务,并在调用otx.Complete时发生错误().这可以.
但我当然不希望嵌套事务在未成功完成时提交!有谁知道这里发生了什么以及我如何能够获得预期的行为?
该数据库是SQL Server 2008 R2.
首先,SQL Server中没有嵌套事务.这个很重要.
其次,两个TransactionScope都使用conn1,因此您(在SQL Server级别)递增@@TRANCOUNT每个BEGIN TRANSACTION
简单说明:在外部事务提交时提交内部事务,因为回滚内部会回滚两个事务
也就是说,COMMIT TRANSACTION(隐含的.Complete和.Dispose)减少@@TRANCOUNT而ROLLBACK TRANSACTION(.Dispose仅暗示)将其恢复为零.所以内部回滚被抑制,因为"没有嵌套事务这样的东西"
如果你在内部'范围内正确使用了conn2,那么它将按预期工作,因为在数据库服务器级别上2个事务是不相关的.哪个是重要的......
| 归档时间: |
|
| 查看次数: |
1880 次 |
| 最近记录: |