如何在多个存储过程中使用事务?

时间:2011-01-24 15:34:53

标签: sql-server sql-server-2005 transactions nested

您可以在一个存储过程中启动事务,然后将其回滚或在嵌套过程中提交吗?

4 个答案:

答案 0 :(得分:10)

提交和回滚具有不同的效果

  • COMMIT减少@@ TRANCOUNT
  • ROLLBACK将其推回零

这是因为SQL Server并不真正支持嵌套事务。

如果您在嵌套的存储过程(而不是事务)中提交或回滚,那么由于启动和输入上的@@ TRANCOUNT不匹配,您将生成错误266

回滚问题可以通过使用SET XACT_ABORT ON来解决,这是“自动回滚”(简单)并且可以抑制错误266.

提交问题......你不能这样。但是,您可以通过在存储的proc条目上注明@@ TRANCOUNT并在零时提交 来控制它发生的位置。

为了正确处理交易,请在此处查看我的答案: Nested stored procedures containing TRY CATCH ROLLBACK pattern?Have I to count transactions before rollback one in catch block in T-SQL?

答案 1 :(得分:2)

您无法在嵌套过程中提交它,但启动事务会将所有嵌套过程包装在其中。因此,该事务适用于嵌套在事务中的所有存储过程。在分布式事务中,数据完整性甚至跨越机器边界。

http://msdn.microsoft.com/en-us/library/ms188929(v=SQL.90).aspx

答案 2 :(得分:1)

您应该将BEGIN TRAN和COMMIT配对在同一个SPROC

如果您再调用另一个也有事务的SPROC,后续的BEGIN TRAN / COMMIT TRAN对将分别递增和递减@@ Trancount。

交易在“最后一次”COMMIT TRAN(@@ Trancount = 1)

上提交

但是,任何ROLLBACK都将始终回滚事务。

MSDN有一个很好的解释。

答案 3 :(得分:0)

是的,有可能。使用C#等编程语言时,使用命令传递连接和事务对象。如果发现任何错误而不是回滚事务:

   string customerConnection = "Connection";
        string query = "insert into temp values ('Data2','data1','data2','data3')";
        string query2 = "update tempcst set data = 'Hello data'";

        SqlConnection myConnection = new SqlConnection(customerConnection);
        myConnection.Open();


        SqlTransaction myTrans = myConnection.BeginTransaction();

 Try{

        int result = executeNonQuery(query, myConnection, myTrans, "");
        i = executeNonQuery(query2, myConnection, myTrans, "");
   myTrans.Commit();}



  catch{
        myTrans.Rollback();
        myConnection.Close();
 }