您可以在一个存储过程中启动事务,然后将其回滚或在嵌套过程中提交吗?
答案 0 :(得分:10)
提交和回滚具有不同的效果
这是因为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();
}