是否需要ROLLBACK TRANSACTION?

net*_*rog 8 sql-server transactions

USE AdventureWorks;
GO
BEGIN TRANSACTION;
GO
DELETE FROM HumanResources.JobCandidate WHERE JobCandidateID = 10;
DELETE FROM HumanResources.JobCandidate WHERE JobCandidateID = 11;
DELETE FROM HumanResources.JobCandidate WHERE JobCandidateID = 12;
GO
COMMIT TRANSACTION;
GO
Run Code Online (Sandbox Code Playgroud)

如果第一个删除语句失败会发生什么?第2和第3个删除语句是否会被执行?该示例没有任何错误处理,是否会在异常情况下保留打开的事务,或者SQL Server会自动回滚事务吗?打开事务=锁定资源,对吧?

我决定是否必须将TRY ... CATCH应用于使用事务的存储过程.

我知道set xact_abort on,但想知道没有它会发生什么.

以下是我在docs中发现的内容 - 控制事务(数据库引擎):

如果错误阻止成功完成事务,SQL Server将自动回滚事务并释放事务持有的所有资源

但是我在其他帖子中读到自动回滚没有被触发.

Jus*_*sel 12

在您的示例中,不使用SET XACT_ABORT ON,即使第一个语句失败,事务也将继续并提交.在您引用的文本中,关键词是if an error **prevents** the successful completion of a transaction,并且DELETE语句失败并不会阻止事务完成.

导致自动回滚的错误示例是在事务中间切断与数据库的连接.在你引用的MSDN文章的下面说:

如果批处理中发生运行时语句错误(例如约束违规),则数据库引擎中的默认行为是仅回滚生成错误的语句.您可以使用SET XACT_ABORT语句更改此行为.执行SET XACT_ABORT ON后,任何运行时语句错误都会导致当前事务的自动回滚.SET XACT_ABORT不会影响编译错误,例如语法错误.

如果需要,使用错误处理来捕获错误和回滚总是一个好主意.

  • 我从许多来源读到,例如[this](https://www.c-sharpcorner.com/UploadFile/84c85b/understanding-transactions-in-sql-server/),事务是**原子的**,从某种意义上说,一切都会成功或失败。然而,在同一个链接中,我看到了他们制作的一个手动处理错误的示例。那么我这样说是否正确,人们应该将事务理解为“应​​该”是原子的,而不是“保证”是原子的? (2认同)

aba*_*hev 6

我更喜欢手动控制流程:

BEGIN TRY
BEGIN TRAN

   -- do work

COMMIT
END TRY
BEGIN CATCH
    ROLLBACK
    RAISERROR (...)
END CATCH
GO
Run Code Online (Sandbox Code Playgroud)