了解transaction.complete的功能如何?

时间:2013-07-29 03:37:42

标签: c# distributed-transactions

大家好我们已经开始使用事务范围了,下面是代码片段。我们需要了解的是,在每次使用连接后,我们的底线是否会处理/关闭特定连接?所以,自关闭以来,transaction.complete如何运作?

using (TransactionScope transScope = new TransactionScope())
{
   try
   {
      string myConnStringLocal = "User Id=***;Password=****;Host=" + globalSettings.settingLocalIP + ";Database=" + globalSettings.settingLocalDB;
      using (MySqlConnection connectionLocal = new MySqlConnection(myConnStringLocal))
      {
         try{
         connectionLocal.Open();
         }
         Catch(Exception e)
         {

         }
         finally{
         connectionLocal.Close();
         }
      }

      string myConnStringCentral = "User Id=***;Password=*****;Host=" + globalSettings.settingCentralIP + ";Database=" + globalSettings.settingCentralDB;
      using (MySqlConnection connectionCentral = new MySqlConnection(myConnStringCentral))
      {
         try{
         connectionCentral.Open();
         }
         Catch(Exception e)
         {

         }
         finally{
         connectionCentral.Close();
         }

      }
      string myConnStringCentralCopy = "User Id=*****;Password=*****;Host=" + globalSettings.settingCentralCopyIP + ";Database=" + globalSettings.settingCentralCopyDB;
      using (MySqlConnection connectionCentralCopy = new MySqlConnection(myConnStringCentralCopy))
      {
         try{
         connectionCentralCopy.Open();
         }
         Catch(Exception e)
         {

         }
         finally{
         connectionCentralCopy.Close();
         }
      }
      transScope.Complete();
      Console.WriteLine("Transaction is completed");
   }
   catch (Exception)
   {
      Console.WriteLine("Transaction is rolled back");
   }
}

3 个答案:

答案 0 :(得分:6)

TransactionScope.Complete告诉所有交易经理他们可以提交此交易。并不能保证一切都会真正提交。调用 完成 方法后,所有事务管理器都会单独启动提交,如果所有事务管理器都成功,则认为事务已成功完成。 您可以参考此link for further details

答案 1 :(得分:4)

当您连接到单个TransactionScope中的多个数据库时,该交易将升级为distributed交易,并由MSDTC使用2-phase commit进行协调。

关于连接关闭 - 这是在TransactionScope内部关闭连接时的特殊情况,在内部由System.Transactions基础架构管理,因此即使连接从您的端关闭,数据库会话仍可能仍处于打开状态。

请参阅MSDN上的说明:

  

如果启用了连接池,则在重置连接时会自动回滚使用Transact-SQL或BeginTransaction的挂起事务。如果关闭连接池,则在调用SqlConnection.Close后回滚事务。通过System.Transactions启动的事务是通过System.Transactions基础结构控制的,不受SqlConnection.Close的影响

编辑根据您的评论,您可以执行以下操作:

try
{
   using (TransactionScope transScope = new TransactionScope())
   {
      string myConnStringLocal = ...;
      using (var connectionLocal = new MySqlConnection(myConnStringLocal))
      {
         connectionLocal.Open();
         // do your DB update 

      } //no need to close connection explicitly, the using() {..} statement does that for you

      string myConnStringCentral = ...;
      using (var connectionCentral = new MySqlConnection(myConnStringCentral))
      {
         connectionCentral.Open();
         // do your DB update

      } //no need to close connection explicitly, the using() {..} statement does that for you

      string myConnStringCentralCopy = ...;
      using (var connectionCentralCopy = new MySqlConnection(myConnStringCentralCopy))
      {         
         connectionCentralCopy.Open();
         // do your DB update

      } //no need to close connection explicitly, the using() {..} statement does that for you

      transScope.Complete();

      Console.WriteLine("Transaction is completed");

   } //no need to dispose transactionScope explicitly, the using() {..} statement does that for you
}
catch (Exception)
{
      // If any exception occurs in the try block above transScope.Complete() line will be caught here
      // and will automatically cause the transaction to rollback.
      Console.WriteLine("Transaction is rolled back");
}

// You can then start new TransactionScope if you want to further update more than one DB in a transactional manner.
try
{
   using (TransactionScope transScope = new TransactionScope())
   {
      //...

   }
}
catch (Exception)
{
     //...
}

答案 2 :(得分:2)

调用Complete方法时,如果没有抛出Exception,则会提交范围内的所有内容。如果代码超出范围而没有Complete,则不会发生任何提交。简而言之,如果您调用Complete方法,那么,如果没有抛出Exceptions,则将提交给定TransactionScope范围内的事务。

另外,我必须补充说,可能还有一个层次结构,TransactionScopes的树。您还可以设置TransactionScope的行为,以便TransactionScope的子范围回滚。