TransactionScope是否隐式应用,直到明确完成?

时间:2013-04-18 21:37:22

标签: c# .net transactionscope

请考虑以下方法。

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()的交易中运行?

(或者我是否误解了某些事情?)

2 个答案:

答案 0 :(得分:4)

逻辑上所有代码都是单个事务。嵌套作用域不一定会创建新事务(除非您使用RequiresNew),因此它将是单个事务。现在,每个范围必须投票才能完成事务,因此如果删除Complete,则在第二个范围内,应该导致整个事务回滚。

DoC也将成为交易的一部分;环境事务将检测新连接并自动登记。

请阅读所有详细信息here,其中说明了注册环境事务的行为以及不同选项RequiresRequiresNewSuppress

另请注意,如果您的连接不使用完全相同的连接字符串,则会自动将整个事务提升为分布式事务。需要注意的事项。

答案 1 :(得分:2)

根据Andy的评论编辑:

似乎在SQL服务器上会发生类似这样的事情:

BEGIN TRANSACTION A

  -- do A's work

  -- B does NOT create a new transaction

    -- do B's work

    -- do C's work

COMMIT TRANSACTION A

如果在new TransactionScope(TransactionScopeOption.RequiresNew)中使用DoB(),则会发生以下情况。

BEGIN TRANSACTION A

  -- do A's work

  BEING TRANSACTION B

    -- do B's work

    -- do C's work

  COMMIT TRANSACTION B
COMMIT TRANSACTION A