2013-01-21 84 views
4

我有以下使用SqlTransaction的代碼。我已經在catch中調用了dispose,並最終阻塞了..但是在調用Dispose()之前,我沒有檢查它是否已經處理。我們如何在調用Dispose()之前檢查SqlTransaction是否已經處理?如何在處理SqlTransaction之前檢查狀態

我參考了MSDN:SqlTransaction.Dispose Method。但那不包括我的問題。

也稱爲http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqltransaction.dispose(v=vs.100).aspx

注:我已經知道TransactionScope擁有SqlTransaction優勢。但我想了解SqlTransaction的dispose。

CODE

using (SqlConnection connection = new SqlConnection(connectionString)) 
     { 
      connection.Open(); 

      SqlTransaction transaction = null; 

      try 
      { 
       transaction = connection.BeginTransaction(); 

       sessionID = GetSessionIDForAssociate(connection, empID, transaction); 
       //Other code 

       //Commit 
       transaction.Commit(); 
      } 
      catch 
      { 
       //Rollback 
       if (transaction != null) 
       { 
        transaction.Rollback(); 
        transaction.Dispose(); 
       } 

       //Throw exception 
       throw; 
      } 
      finally 
      { 
       if (transaction != null) 
       { 
        transaction.Dispose(); 
       } 
      } 

回答

7

我們如何檢查SqlTransaction是否已在調用Dispose()之前處理過 ?

您不需要。調用兩次處置不會導致任何問題。

Dispose - MSDN

如果對象的Dispose方法被調用一次以上,該對象 必須忽略第一個之後的所有呼叫。如果對象的Dispose方法被多次調用,則該對象不得拋出 異常。如果 資源已被處置,Dispose以外的其他方法可能會拋出ObjectDisposedException。

但是,如果您只想調用Dispose一次,那麼您可以使用布爾標誌設置事務處置時間或者可以將其設置爲null。或者由於finally塊總是被調用,所以刪除呼叫以在catch塊中處置。

由於SqlTransaction實現了IDisposable,,如果您在使用塊時使用它,它會更好。喜歡的東西:

using (SqlConnection connection = new SqlConnection(connectionString)) 
{ 
    connection.Open(); 

    using (SqlTransaction transaction = connection.BeginTransaction()) 
    { 
     try 
     { 
      sessionID = GetSessionIDForAssociate(connection, empID, transaction); 
      //Other code 

      //Commit 
      transaction.Commit(); 
     } 
     catch 
     { 
      //Rollback 
      if (transaction != null) 
      { 
       transaction.Rollback(); 
      } 

      //Throw exception 
      throw; 
     } 
    } 
} 

由於使用塊的行爲像try/finally塊,這將確保其完成後處置交易(即使發生異常)。所以你不必手動撥打Dispose

2

添加transaction=null你打電話後處理,然後將現有測試將正常工作。

2

爲什麼要檢查它是否已被處置?你可以通過簡單地從你的catch塊省略呼叫避免調用Dispose兩次:

using (SqlConnection connection = new SqlConnection(connectionString)) 
{ 
    connection.Open(); 

    SqlTransaction transaction = null; 

    try 
    { 
     transaction = connection.BeginTransaction(); 

     sessionID = GetSessionIDForAssociate(connection, empID, transaction); 
     //Other code 

     //Commit 
     transaction.Commit(); 
    } 
    catch 
    { 
     //Rollback 
     if (transaction != null) 
     { 
      // No need to dispose here - finally is always called 
      transaction.Rollback(); 
     } 

     //Throw exception 
     throw; 
    } 
    finally 
    { 
     if (transaction != null) 
     { 
      // Always called, so no need to dispose elsewhere. 
      transaction.Dispose(); 
     } 
    } 
2

取下catch塊.Dispose()通話。最後是總是執行,所以你這樣試着兩次來處理事務。

它不回答「我怎麼知道它是否已經處置」,但可能解決您的問題。

相關問題