考虑以下方法。
DoA()
{
using (TransactionScope scope = new TransactionScope)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
SqlCommand command = new SqlCommand(query, connection);
command.ExecuteNonReader();
DoB();
scope.Complete();
}
}
}
DoB()
{
using (TransactionScope scope = new TransactionScope)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
SqlCommand command = new SqlCommand(query, connection);
command.ExecuteNonReader();
DoC();
scope.Complete();
}
}
}
DoC()
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
SqlCommand command = new SqlCommand(query, connection);
command.ExecuteNonReader();
}
}
如果我们调用
DoA()
,那么DoB()
和DoC()
中的后续交互是否在DoA()
与SQL Server有关的事务上下文中运行? DoC()是否在DoA()
和DoB()
事务的上下文中运行?(或者我严重误解了什么?)
最佳答案
从逻辑上讲,所有代码都是单个事务。嵌套作用域不一定会创建一个新事务(除非您使用RequiresNew),因此它将是单个事务。现在,每个作用域都必须投票完成事务,因此在第二个作用域中,如果删除Complete
,将导致整个事务回滚。
合格证明也将成为交易的一部分;环境事务将检测到新连接并自动加入。
请阅读所有细节here,这些细节说明了注册环境事务的行为以及不同的选项Requires
,RequiresNew
和Suppress
。
还要注意,如果您的连接不使用完全相同的连接字符串,这将自动将整个事务提升为分布式事务。只是要提防的东西。