【问题标题】:SQL Server BEGIN/END vs BEGIN TRANS/COMMIT/ROLLBACKSQL Server BEGIN/END 与 BEGIN TRANS/COMMIT/ROLLBACK
【发布时间】:2016-02-11 03:10:32
【问题描述】:

我一直试图在网络上查找有关这些陈述之间差异的信息,在我看来它们是相同的,但我找不到对这两者的确认或任何类型的比较。

这样做有什么区别:

BEGIN
    -- Some update, insert, set statements
END

然后这样做

BEGIN TRANS
    -- Some update, insert, set statements
COMMIT TRANS

?

请注意,只有在某些异常或超时或其他一般故障的情况下才需要回滚,不会有条件回滚的原因。

【问题讨论】:

  • 了解 SQL Server 语法的第一个位置是联机丛书,它是 SQL Server 附带的文档。
  • 您尚未标记已接受的答案,但我当然希望您了解其中的区别,它们是完全不同的。如果不理解这个基本点,你就会错过 SQL 最基本的点之一。

标签: sql sql-server transactions


【解决方案1】:

BEGIN 和 END 处理代码块。它们类似于您在许多语言中看到的花括号:

if (somethingIsTrue)
{ // like BEGIN
    // do something here
} // like END

在 SQL 中,这是:

if somethingIsTrue
BEGIN
    -- do something here
END

BEGIN TRANCOMMITROLLBACK 开始和结束事务。他们没有指定新的代码块;它们只标记事务边界。

请注意,您可以在单独的代码块中编写 BEGIN TRANCOMMIT。例如,如果您希望代码成为事务的一部分,但如果代码已经在事务中,您不想开始新的,您可以执行以下操作:

declare @TranStarted bit = 0
if @@trancount = 0
begin
    set @TranStarted = 1
    begin tran
end

-- ... do work ...

if @TranStarted = 1
begin
    commit
    set @TranStarted = 0
end

【讨论】:

  • 我认为说它们“类似于 'if' 构造”可能有点误导。我喜欢@Mike Mooney 的比喻“像 C#/C++/Java 中的大括号 {}”
  • 因此,如果在 begin end 语句中发生问题,则不会回滚任何内容,但如果它发生在 begin transaction..那么事务将被回滚。对吗?
  • @Baahubali 答案取决于XACT_ABORT 的设置。如果XACT_ABORT 开启,那么是的,事务将回滚。如果不是,则不是,事务很可能保持打开状态——假设某种严重错误不会使其处于不确定状态。检查XACT_STATE 以查看事务是否可用。但我建议开启XACT_ABORT
  • 但我的理解是begin end 不启动事务?在我的场景中,xact_abort 是关闭的,如果在 begin end 中有一批插入语句并且其中一个失败,我猜其他人会继续?
  • @Baahubali 如果xact_abort 关闭,则在出错后如果可能继续执行。 (这是一种简化。)beginend 与事务无关。 begin trancommitrollback 标记事务的开始和结束。
【解决方案2】:

常规的 BEGIN 和 END 不用于事务。相反,它们只是为了表明某些代码块是一个单元,就像 C#/C++/Java 中的大括号 {}。

如果您有一个执行 10 项操作的 IF 语句或 WHILE 循环,则需要将它们包含在 BEGIN/END 中,以便 SQL Server 知道应作为该条件的一部分执行 10 条语句的整个列表。

【讨论】:

    【解决方案3】:

    这两种说法完全不同。

    BEGIN..END 标记代码块,例如在 if 语句中

    IF @something = 1
    BEGIN
      -- Do something when @something is equal to 1
    END
    

    BEGIN TRANS..COMMIT TRANS 将封闭块包装在事务中,如果发生错误,将根据服务器设置回滚事务。

    【讨论】:

      【解决方案4】:

      应该提到,有一个Begin;在 PostgreSQL 中,这也启动了一个事务块,起初这让我很困惑。

      http://www.postgresql.org/docs/9.0/static/sql-begin.html

      "BEGIN启动一个事务块,即BEGIN命令之后的所有语句将在一个事务中执行,直到给出显式的COMMIT或ROLLBACK。默认情况下(没有BEGIN),PostgreSQL以“自动提交”模式执行事务,即每条语句都在自己的事务中执行,并在语句末尾隐式执行一次提交(如果执行成功,则执行回滚)。”

      【讨论】:

        【解决方案5】:

        我还没有看到 END TRANS :)

        我认为我们仅将 END 用于 BEGIN 关键字而不用于 BEGIN trans 我们对 BEGIN trans 使用提交或回滚

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-10-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-05-18
          • 1970-01-01
          • 2013-10-11
          • 2012-12-04
          相关资源
          最近更新 更多