【问题标题】:Correct use of transactions in SQL ServerSQL Server 中事务的正确使用
【发布时间】:2012-04-26 13:46:53
【问题描述】:

我有 2 个命令,需要它们都正确执行或都不执行。所以我想我需要一个事务,但我不知道如何正确使用它。

以下脚本有什么问题?

BEGIN TRANSACTION [Tran1]

INSERT INTO [Test].[dbo].[T1]
    ([Title], [AVG])
VALUES ('Tidd130', 130), ('Tidd230', 230)

UPDATE [Test].[dbo].[T1]
  SET [Title] = N'az2' ,[AVG] = 1
  WHERE [dbo].[T1].[Title] = N'az'

COMMIT TRANSACTION [Tran1]
GO

INSERT命令执行了,但是UPDATE命令有问题。

如果其中任何一个命令在执行过程中出现错误,我该如何实现它以回滚这两个命令?

【问题讨论】:

    标签: sql sql-server database tsql transactions


    【解决方案1】:

    添加一个try/catch块,如果事务成功则提交更改,如果事务失败则回滚事务:

    BEGIN TRANSACTION [Tran1]
    
      BEGIN TRY
    
          INSERT INTO [Test].[dbo].[T1] ([Title], [AVG])
          VALUES ('Tidd130', 130), ('Tidd230', 230)
    
          UPDATE [Test].[dbo].[T1]
          SET [Title] = N'az2' ,[AVG] = 1
          WHERE [dbo].[T1].[Title] = N'az'
    
          COMMIT TRANSACTION [Tran1]
    
      END TRY
    
      BEGIN CATCH
    
          ROLLBACK TRANSACTION [Tran1]
    
      END CATCH  
    

    【讨论】:

    • 不应该把BEGIN TRANSACTION [Tran1]放在TRY里面吗?无论如何 - 非常简单和优雅的代码。
    • @PiotrNawrot 否,如果事务创建失败,则无需在 catch 中回滚。
    • 如果您想查看错误,请将其包含在 catch 中:SELECT ERROR_MESSAGE() AS ErrorMessage;
    • @KevinLeStarge 或简单的THROW;,如果您使用的是 SQL Server >= 2012,如上所述 here
    【解决方案2】:

    在存储过程的开头应该输入SET XACT_ABORT ON 来指示Sql Server 自动回滚事务以防出错。如果省略或设置为 OFF,则需要在每个语句之后测试 @@ERROR 或使用 TRY ... CATCH rollback 块。

    【讨论】:

    • 换句话说,除非您先 SET XACT_ABORT ON,否则您的事务不是原子的。
    • 带有下划线的url很难看,但是XACT_ABORT中有下划线
    【解决方案3】:

    简单的方法:

    CREATE TABLE T
    (
        C [nvarchar](100) NOT NULL UNIQUE,
    );
    
    SET XACT_ABORT ON -- Turns on rollback if T-SQL statement raises a run-time error.
    SELECT * FROM T; -- Check before.
    BEGIN TRAN
        INSERT INTO T VALUES ('A');
        INSERT INTO T VALUES ('B');
        INSERT INTO T VALUES ('B');
        INSERT INTO T VALUES ('C');
    COMMIT TRAN
    SELECT * FROM T; -- Check after.
    DELETE T;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-07
      • 1970-01-01
      • 1970-01-01
      • 2014-12-19
      相关资源
      最近更新 更多