事务中显式提交的使用

4

在我的事务中添加显式提交与自动提交有什么区别吗?

CREATE TABLE #test (test_col INT) 

使用明确的 COMMIT

INSERT #test
VALUES (11)

BEGIN TRY
    BEGIN TRAN DELETE_TRAN

    DELETE FROM #test

    COMMIT TRAN DELETE_TRAN
END TRY

BEGIN CATCH
    ROLLBACK TRAN DELETE_TRAN

    SELECT ERRORMESSAGE = Error_message()
END CATCH

SELECT *
FROM   #test

没有显式提交

INSERT #test
VALUES (11)

BEGIN TRY
    BEGIN TRAN DELETE_TRAN

    DELETE FROM #test
END TRY

BEGIN CATCH
    ROLLBACK TRAN DELETE_TRAN

    SELECT ERRORMESSAGE = Error_message()
END CATCH

SELECT *
FROM   #test 

这两种方法都可以实现相同的功能。有人能告诉我它们之间有什么区别或者优劣吗?


好问题。这可能更适合Stack DBA - David Rushton
@destination-data - 我需要在上述网站上发布同样的问题吗? - ask_Overflow
不,我被告知不要这样做!显然这是不好的习惯。如果你想的话,你可以标记这个问题,认为它不属于这个网站。管理员会将其移动到正确的位置。 - David Rushton
@destination-data 成功标记了它。 - ask_Overflow
2个回答

3
我能看到的主要功能区别是,在第一个示例中使用显式COMMIT可以确保表格(在本例中是临时表)在最后的SELECT语句中被解锁。而在第二个示例中,除非其他用户执行脏读取(即WITH(NOLOCK)等),否则SELECT将被阻止,直到触发隐式COMMIT。
由于您使用了一个临时表,这并不一定是大问题,但如果您将其更改为实际表,则在该表上由于打开TRAN而锁定时间会有所不同。这意味着并发调用将被阻塞更长时间,并且会在彼此身后堆积。或者在脏读取的情况下,其他连接将无法看到您的更改。
同时,明确关闭SQL中打开的任何TRAN也是一项良好的标准实践,以确保您不依赖于调用者尝试提交TRAN。请记住,如果与SQL的连接关闭并且TRAN没有COMMIT,则TRAN将自动得到ROLLBACK。

恰好找到了这个答案。非常感谢! - ask_Overflow
在我的原始场景中,它不是临时表。 - ask_Overflow

-1

隐式提交比显式提交慢,我们可以根据需求打开或关闭隐式提交。有关更多详细信息,请参阅此链接:SQL Server - 性能和其他故事


有任何功能上的区别吗? - ask_Overflow
以上查询(没有显式的COMMIT)是否会导致任何错误,例如当前事务无法提交,也无法支持写入日志文件的操作。回滚事务。当我执行一个从未在过去一年中抛出此类错误的过程时,我遇到了这个错误。 - ask_Overflow
@ask_Overflow,然后提交。我怀疑应用了数据库补丁,这就是为什么你以前从未遇到过错误的原因。然而,打开一个事务却没有通过提交或可能的回滚显式地关闭它是一种不好的做法。 - HLGEM

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接