2016-08-24 39 views
3

我正在開發一些已由其他開發人員開發的系統。 在那個系統中,他們調用了一個存儲過程,用於在C#中將循環中的記錄插入到循環中,而不使用用戶定義表類型。在調用C#循環中的SQL存儲過程時處理事務

而我需要做的是將事務添加到這種情況。但問題是我不知道有交易的地方。

我想知道是否在C#代碼中翹曲循環或存儲過程中。

回答

2

你只能有它的C#循環中。在過程退出之前,在過程內啓動的事務必須提交。 SQL Server在運行過程之前和之後檢查@@TRANCOUNT,並且如果結果不匹配,則會引發異常。所以過程不可能啓動一個必須由調用者提交的事務。

最簡單的認爲做的是包裝你的C#代碼在交易範圍:

using(var scope = new TransactionScope(
     TransactionScopeOption.Required, 
     new TransactionOptions() { 
     IsolationLevel = IsolationLevel.ReadCommitted 
     })) { 
    // Do the work here 
    scope.Complete(); 
} 

注意,通過IsolationLevel = IsolationLevel.ReadCommittedcritical

0

在SQL Server

BEGIN TRY 
BEGIN TRAN 

-- DO YOUR INSERT /UPDATE /DELETE HERE 

COMMIT TRAN T1 
END TRY 
BEGIN CATCH 
-- // ROLL BACK IF ERROR OCCURS 

ROLLBACK TRAN T1 
END CATCH 

在C#

using(TransactionScope tran = new TransactionScope()) { 

    // DO YOUR INSERT /UPDATE /DELETE HERE 

    tran.Complete(); 
} 
+0

兩個(SQL Server中,C#)將是相同的多次往返。爲了兩者相同,它需要使用TVP –

1

在這種情況下,交易需要在C#代碼開始,您有以下選擇:

  • 使用TransactionConnection object

    using (var conn = new SqlConnection(connString)) 
    { 
    conn.Open(); 
    using (IDbTransaction tran = conn.BeginTransaction()) 
    { 
        try 
        { 
         // transactional code... 
         using (SqlCommand cmd = conn.CreateCommand()) 
         { 
          // Loop the Insert operation here 
          cmd.CommandText = "INSERT Operation"; 
          cmd.Transaction = tran as SqlTransaction; 
          cmd.ExecuteNonQuery(); 
         } 
         tran.Commit(); 
        } 
        catch(Exception ex) 
        { 
         tran.Rollback(); 
         throw; 
        } 
    } 
    } 
    
  • 使用Implicit or Explicit Ambient transaction
  • 使用TransactionScope (隱式)環境事務(例外,它是一個自動回滾)

    using (var scope = new TransactionScope(
        TransactionScopeOption.Required, 
        new TransactionOptions() { 
        IsolationLevel = IsolationLevel.ReadCommitted 
        })) 
    { 
    using (var conn = new SqlConnection(connString)) 
    { 
        conn.Open(); 
    
        using (SqlCommand cmd = conn.CreateCommand()) 
        { 
         // Loop the Insert operation here 
         cmd.CommandText = "INSERT Operation"; 
         cmd.ExecuteNonQuery(); 
        }     
    }  
    scope.Complete(); 
    } 
    
    • 使用CommittableTransaction(明確的)環境事務

      var tran = new CommittableTransaction(); 
      using (var conn = new SqlConnection(connString)) 
      { 
      conn.Open(); 
      try 
      { 
          conn.EnlistTransaction(tran); 
      
      using (SqlCommand cmd = conn.CreateCommand()) 
      { 
          // Loop the Insert operation here 
          cmd.CommandText = "INSERT Operation"; 
          cmd.ExecuteNonQuery(); 
      } 
          tran.Commit(); 
      } 
      catch(Exception ex) 
      { 
          tran.Rollback(); 
          throw; 
      }   
      } 
      

對於Ambient transactions,請記住,如果你打開多個連接,然後將得到local to global transaction提升,因此要求MSDTC並且對性能有影響。

查看以下鏈接:只有當所有的插入/ DML發生在同一個事務上下文,這是不是這裏的情況,因爲刀片是

http://www.codeproject.com/Articles/690136/All-About-TransactionScope