2013-03-20 70 views
3

我在TransactionScope中使用两个SQLConnection是(伪)代码是否正确?使用语句在哪里完成TransactionScope?

using (TransactionScope ts= new TransactionScope(TransactionScopeOption.RequiresNew)) 
    { 
    using (SqlConnection connection1 = new SqlConnection(ConnectionString1)) 
     { 
     (...) 
     } 

    using (SqlConnection connection2 = new SqlConnection(ConnectionString2)) 
     { 
      (...) 
     } 

    ts.Complete(); 
    } 

还是应该用这个?

using (TransactionScope ts= new TransactionScope(TransactionScopeOption.RequiresNew)) 
    { 
    using (SqlConnection connection1 = new SqlConnection(ConnectionString1)) 
     { 
     (...) 
     using (SqlConnection connection2 = new SqlConnection(ConnectionString2)) 
      { 
      (...) 
      ts.Complete(); 
      } 
     } 
    } 

第一个代码更好,因为它允许我在方法中提取命令。但是我担心的是,在这种情况下,连接是在范围完成之前处理的,是否将TransactionScope纳入足以防止这种情况?

回答

1

嵌套连接处理完毕后,调用Complete没有任何问题。事务的生命周期有意地大于SQL连接的生命周期,并且您可以继续与其交互,而与任何其他连接的生命周期无关。

所以是的,在你的第一个例子中,你在连接处理后调用Complete并且这很好

根据Transaction Scope以及this page on how to use transaction scopes文档中的示例,您可以看到事务可以在连接处理完成后完成。

+0

以下Servy建议我已经在第一个示例之后编写了我的代码,并且我能够测试它的行为如预期的那样(如果在事务范围内没有调用.Complete(),则连接将回滚 – floqui 2013-03-21 08:43:55

0

还有第三种可能性:

using (TransactionScope ts= new TransactionScope(TransactionScopeOption.RequiresNew)) 
using (SqlConnection connection1 = new SqlConnection(ConnectionString1)) 
using (SqlConnection connection2 = new SqlConnection(ConnectionString2)) 
{ 
    // ... 
    ts.Complete() 
} 
+3

这与他提到的第二个相同,只是没有{} – Brendan 2013-03-20 15:01:27

1

在第一个示例中,两个连接都在ts.Complete()被调用之前处理,这不是问题,因为ts.Complete()方法不使用连接:

  • 既连接该方法内声明本地和将超出范围为任何其他方法
  • 连接不传递给ts.Complete()方法,以使它们范围

在你的第二个例子,当两个连接仍然存在时调用ts.Complete()方法,但是,它们不传递给方法,因此不能使用。

这意味着这两种方法都可以正常工作,并且在调用ts.Complete()之前是否放置连接并不重要。

+0

'如果你需要在连接被处理之前调用ts.Complete()'什么使你认为需要完成?我没有看到它需要完成的迹象。 – Servy 2013-03-20 15:16:23

+0

@Servy从OP:'但是我担心的是,在这种情况下,连接是在完成范围之前处理的。 – 2013-03-20 15:18:09

+0

是的,他们是,*,这根本不是问题*。这就是正确的答案。 – Servy 2013-03-20 15:19:19