2015-02-09 83 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