我有一个采用这种格式的存储过程(简化):
SET XACT_ABORT ON
GO
BEGIN TRY
BEGIN TRANSACTION myTransaction
--multiple CRUD operations
--insert statement inserts records into table with unique constraint.
IF (XACT_STATE()) = 1
BEGIN
COMMIT TRANSACTION myTransaction
RAISERROR ('TRANSACTION COMMITTED', 0, 1) WITH NOWAIT
RETURN 1
END
END TRY
BEGIN CATCH
IF (XACT_STATE()) = -1
BEGIN
SELECT
ERROR_NUMBER() AS ErrorNumber,
ERROR_SEVERITY() AS ErrorSeverity,
ERROR_STATE() AS ErrorState,
ERROR_PROCEDURE() AS ErrorProcedure,
ERROR_LINE() AS ErrorLine,
ERROR_MESSAGE() AS ErrorMessage
ROLLBACK TRANSACTION myTransaction
RAISERROR ('TRANSACTION ROLLED BACK', 0, 1) WITH NOWAIT
RETURN 0
END
IF (XACT_STATE()) = 1
BEGIN
COMMIT TRANSACTION myTransaction
RAISERROR ('TRANSACTION COMMITTED', 0, 1) WITH NOWAIT
RETURN 1
END
END CATCH
我试图解决SP尝试将记录插入具有唯一约束的表中的问题,但它失败了,因此它不会插入任何内容。问题是,这似乎不会触发catch块,或者更改XACT_STATE()以反映出存在问题。我究竟做错了什么?
所需的功能是,如果违反约束,整个事务将失败并回滚。
答案 0 :(得分:6)
当您正在使用
时Set Xact_Abort On
我的理解是,当您到达任何Catch部分时,事务已经回滚。没有什么可以回滚的。
还有一些我似乎记得的事情,有时候这样的实例会完全绕过Catch。
答案 1 :(得分:4)
你已经完成了一个相当简单的任务,我只是完全废弃了XACT_ABORT()函数并且只是坐下来试试.catch块。类似......
BEGIN TRY
BEGIN TRANSACTION myTransaction
--multiple CRUD operations
--insert statement inserts records into table with unique constraint.
-- if an error occurs in any of the above statements the control will
-- jump to Catch block and the Commit trans never gets executed
COMMIT TRANSACTION myTransaction
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0
BEGIN
ROLLBACK TRANSACTION myTransaction
END
SELECT
ERROR_NUMBER() AS ErrorNumber,
ERROR_SEVERITY() AS ErrorSeverity,
ERROR_STATE() AS ErrorState,
ERROR_PROCEDURE() AS ErrorProcedure,
ERROR_LINE() AS ErrorLine,
ERROR_MESSAGE() AS ErrorMessage
END CATCH