【问题标题】:Use of explicit commit in transaction在事务中使用显式提交
【发布时间】:2016-06-05 03:46:12
【问题描述】:

在我的transaction 中添加explicit commit 与自动提交有什么区别。

CREATE TABLE #test (test_col INT) 

显式提交

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

没有明确的 COMMIT

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。
  • @destination-data - 我是否必须在上述网站上发布同样的问题?
  • 不,我被告知这样做了!显然这是一种糟糕的形式。如果您愿意,可以将问题标记为离题 - 错误的站点。然后模组会移动它。
  • @destination-data 标记成功

标签: sql sql-server transactions commit rollback


【解决方案1】:

隐式提交比显式提交慢,我们可以根据我们的要求打开或关闭隐式,更多细节可以看这个链接:SQL Server – performance and other stories

【讨论】:

  • 功能上有区别吗?
  • 上述查询(Without explicit COMMIT) 是否会导致类似The current transaction cannot be committed and cannot support operations that write to the log file. Roll back the transaction. 的任何错误。我在执行一个在过去 1 年中从未抛出任何此类错误的程序时遇到此错误
  • @ask_Overflow,然后添加提交。我怀疑应用了数据库补丁,这就是为什么您以前从未收到错误的原因。但是,打开事务而不通过提交或可能的回滚显式关闭它是一种糟糕的做法。
【解决方案2】:

我可以看到的主要功能差异是,通过在第一个示例中使用显式 COMMIT,您可以确保表(在本例中为临时表)在最后为 SELECT 语句解锁。而在您的第二个示例中,除非他们执行脏读(即 WITH (NOLOCK) 等),否则 SELECT 将被其他用户阻止,直到触发隐式 COMMIT。

由于您使用的是临时表,这不一定是什么大问题,但如果您要将其更改为实际表,那​​么由于打开的 TRAN,该表被锁定的时间会有所不同在上面。这意味着并发调用将阻塞更长的时间并相互叠加。或者在脏读的情况下,其他连接还看不到您的更改。

显式关闭您在 SQL 中打开的任何 TRAN 也是一个很好的标准做法,这样您就不会依赖调用者来尝试提交 TRAN。请记住,如果与 SQL 的连接已关闭且 TRAN 没有 COMMIT,则 TRAN 会自动获得 ROLLBACK。

【讨论】:

  • 正是在寻找这个答案。非常感谢
  • 在我原来的场景中它不是临时表
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-17
相关资源
最近更新 更多