Microsoft在tsql中有以下try ... catch示例:
USE AdventureWorks;
GO
-- SET XACT_ABORT ON will render the transaction uncommittable
-- when the constraint violation occurs.
SET XACT_ABORT ON;
BEGIN TRY
BEGIN TRANSACTION;
-- A FOREIGN KEY constraint exists on this table. This
-- statement will generate a constraint violation error.
DELETE FROM Production.Product
WHERE ProductID = 980;
-- If the delete operation succeeds, commit the transaction. The CATCH
-- block will not execute.
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
-- Test XACT_STATE for 0, 1, or -1.
-- If 1, the transaction is committable.
-- If -1, the transaction is uncommittable and should
-- be rolled back.
-- XACT_STATE = 0 means there is no transaction and
-- a commit or rollback operation would generate an error.
-- Test whether the transaction is uncommittable.
IF (XACT_STATE()) = -1
BEGIN
PRINT 'The transaction is in an uncommittable state.' +
' Rolling back transaction.'
ROLLBACK TRANSACTION;
END;
-- Test whether the transaction is active and valid.
IF (XACT_STATE()) = 1
BEGIN
PRINT 'The transaction is committable.' +
' Committing transaction.'
COMMIT TRANSACTION;
END;
END CATCH;
GO
以上示例的来源:Using TRY...CATCH in Transact-SQL
我不明白你为什么要提交一个导致异常的事务。似乎至少有9次你想要IF(XACT_STATE())!= 0 ROLLBACK TRANSACTION。你为什么要在一个干净的石板上取得部分成功呢?
答案 0 :(得分:0)
此示例完全错误。有一个try-catch块来处理密钥副本并恢复并执行备用操作(可能是更新而不是插入)是可以理解的。但是如果成功的话,有一段代码可以使用COMMITS,但是会在发生错误的情况下使事务保持打开状态,甚至更多,默默地吞下错误只是介意吹。这段代码是一大堆蠕虫。
在我的网站上有一个正确的示例procedure template that handles errors and transactions,允许嵌入式交易恢复并继续错误正确。在错误的情况下您希望处理恢复的典型示例是批处理:当您在批处理中前进时,在每个记录之前保存点然后尝试处理。如果处理失败,则将记录保存在失败的表中,并继续而不会丢失整批。
<强>更新强>
大笑,我也错过了捕获中的提交。然后就像我原来的评论那样糟糕。我仍然更喜欢我的模板,它使用保存点并允许嵌套事务。