用于确保事务(全部或没有)的存储过程调用模板


CREATE PROCEDURE dbo.[usp_SampleProcedure]
AS
BEGIN
BEGIN TRY
BEGIN TRANSACTION
EXEC dbo.sp_sp1
EXEC dbo.sp_sp2
EXEC dbo.sp_sp3

COMMIT TRANSACTION
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0
ROLLBACK TRANSACTION;
INSERT INTO dbo.dbErrorLogs (UserName, ErrorNumber, ErrorState, ErrorSeverity, 
ErrorLine, ErrorProcedure, ErrorMessage, ErrorOccuredOn)
VALUES (SUSER_SNAME(), ERROR_NUMBER(), ERROR_STATE(), ERROR_SEVERITY(),
ERROR_LINE(), ERROR_PROCEDURE(), ERROR_MESSAGE(), GETDATE())
END CATCH
END

在上述存储过程中,有对sp1、sp2、sp3的调用。

  1. 这个模板将确保所有或没有事务的行为,还是我需要将xact_abort设置为true?

  2. 如果sp1, sp2, sp3都没有在它们内部实现事务概念,那么在上述模板上的回滚将确保sp1, sp2, sp3的效果被逆转。但是,如果在sp2中存在事务/提交,假设sp2导致提交,假设sp3有一个错误导致示例模板执行回滚。这能确保sp2的效应被逆转吗?

XACT_ABORT ON解决了打开事务问题,但代价是在CATCH块中实现日志记录(如果有的话)。

但"NonexistingTable"这类问题不应该出现在生产环境中。比如,为什么要使用不存在的表部署SP ?奇怪的事情。您应该有适当的QA,并且您的部署脚本应该在生产环境中运行之前进行验证。

https://social.technet.microsoft.com/wiki/contents/articles/40078.sql-server-set-xact-abort-vs-try-catch.aspx

如果SET XACT_ABORT为OFF,则只有引发错误的语句被回滚,事务继续处理其他语句,这也取决于错误的严重程度,即使SET XACT_ABORT为OFF,整个事务也可能被回滚。

https://sqlskull.com/2020/02/22/sql-server-set-xact_abort/

最新更新