2015-02-09 79 views
-1

我用這個命令在多行插入多條記錄,如果插入不成功,我怎樣才能鎖定我的命令和回滾更改?如何鎖定插入多個表中?

SqlCommand cmd = new SqlCommand(); 

     string s = @" 

       declare @one_id int; 

       INSERT INTO tbl_one(o1,o2,o3) VALUES(@o1,@o2,@o3); 

       set @one_id=SCOPE_IDENTITY(); 

       INSERT INTO tbl_two(t1,t2,f3) VALUES(@t1,@t2,@one_id); 
       INSERT INTO tbl_two(t1,t2,f3) VALUES(@t3,@t4,@one_id); 
       INSERT INTO tbl_two(t1,t2,f3) VALUES(@t5,@t6,@one_id); 
       "; 

     cmd.CommandText =s; 
+1

使用交易:http://www.codeproject.com/Articles/10223/Using-Transactions-in-ADO-NET – 2015-02-09 08:45:13

回答

7

當然你熟悉try catch語句,所以使用它。

總結您的語句在BEGIN TRANSACTION和COMMIT,像這樣:

 string s = @" 
     BEGIN TRY 
      BEGIN TRANSACTION 
       declare @one_id int; 

       INSERT INTO tbl_one(o1,o2,o3) VALUES(@o1,@o2,@o3); 

       set @one_id=SCOPE_IDENTITY(); 

       INSERT INTO tbl_two(t1,t2,f3) VALUES(@t1,@t2,@one_id); 
       INSERT INTO tbl_two(t1,t2,f3) VALUES(@t3,@t4,@one_id); 
       INSERT INTO tbl_two(t1,t2,f3) VALUES(@t5,@t6,@one_id); 
      COMMIT 
     END TRY 
     BEGIN CATCH 
      IF @@TRANCOUNT > 0 
       ROLLBACK 
     END CATCH 
     "; 

如果你的語句之一將失敗,CATCH塊將啓動。

祝你好運。

+0

謝謝,但你能描述一些關於@@ TRANCOUNT的東西嗎? – Mike 2015-02-09 09:16:49

+3

@@ TRANCOUNT - >「返回當前連接上發生的BEGIN TRANSACTION語句的數量」請參閱https://msdn.microsoft.com/zh-cn/library/ms187967.aspx – 2015-02-09 09:24:29

2

可以開始交易和管理SQL代碼中的錯誤羅伊建議,或者您也可以在客戶端做:

using (SqlConnection cn = CreateConnection()) 
using (SqlCommand cmd = CreateMyCommand(cn)) 
{ 
    cn.Open(); 
    using (SqlTransaction tx = cn.BeginTransaction()) 
    { 
     cmd.Transaction = tx; 
     cmd.ExecuteNonQuery(); 
     tx.Commit(); 
    }  
} 

請注意,此處不需要catch塊,因爲如果某事失敗,事務將回滾到tx.Dispose()。如果失敗了,tx.commit不會被調用,但tx.Dispose總是被調用,因爲使用了block。如果事務先前未提交,則Tx.Dispose回滾事務。

+0

哪個更好?客戶端或SQL服務器端?它在這種情況下阻止併發問題嗎? – Mike 2015-02-09 10:25:42

+1

沒有什麼可以防止併發問題。樂觀的併發策略,隔離級別和事務有助於處理它們,但這些問題不會神奇地消失。 – 2015-02-09 10:53:07

+1

恕我直言,沒有一個比另一個好。我認爲這是一個偏好問題,他們的行爲幾乎是一樣的,但微妙的不同。 – 2015-02-09 10:55:48