考虑以下方法。

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,这些细节说明了注册环境事务的行为以及不同的选项RequiresRequiresNewSuppress

还要注意,如果您的连接不使用完全相同的连接字符串,这将自动将整个事务提升为分布式事务。只是要提防的东西。

10-07 20:01
查看更多