【问题标题】:Atomic Upgrade Scripts原子升级脚本
【发布时间】:2009-10-28 15:02:49
【问题描述】:

对于我的数据库升级脚本,我通常只有一个长脚本,用于对该数据库版本进行必要的更改。但是,如果一个语句在脚本执行到一半时失败,它会使数据库处于不一致的状态。

如何使整个升级脚本成为一个原子操作?我尝试将所有语句包装在事务中,但这不起作用。即使 SET XACT_ABORT ON,如果一个语句失败并回滚事务,其余语句仍会继续执行。我想要一个不需要我在每个语句之前写 IF @@TRANCOUNT > 0... 的解决方案。例如:

SET XACT_ABORT ON;
GO

BEGIN TRANSACTION;
GO

CREATE TABLE dbo.Customer
(
        CustomerID int NOT NULL
    ,   CustomerName varchar(100) NOT NULL
);
GO

CREATE TABLE [dbo].[Order]
(
        OrderID int NOT NULL
    ,   OrderDesc varchar(100) NOT NULL
);
GO

/* This causes error and should terminate entire script. */
ALTER TABLE dbo.Order2 ADD
    A int;
GO

CREATE TABLE dbo.CustomerOrder
(
        CustomerID int NOT NULL
    ,   OrderID int NOT NULL
);
GO

COMMIT TRANSACTION;
GO

【问题讨论】:

    标签: sql sql-server-2005 tsql


    【解决方案1】:

    Red-Gate 和其他比较工具的工作方式与您描述的完全一样...它们在每个语句之后检查 @@ERROR 和 @@TRANCOUNT,将其塞入 #temp 表中,最后他们检查 #临时表。如果发生任何错误,它们会回滚事务,否则它们会提交。我相信您可以更改任何生成更改脚本的工具来添加这种逻辑。 (或者,您可以使用已经为您创建原子脚本的工具,而不是重新发明轮子。)

    【讨论】:

    • 你能推荐任何上述工具吗?
    • 我在这篇博文中列出了很多:is.gd/4H8iZ(我对 Red-Gate 产品有丰富的经验,并强烈推荐它。我对其他任何产品都没有太多经验。 Apex产品是可比的,但RG在这里根深蒂固,所以我继续使用它。)
    【解决方案2】:

    类似:

    TRY
     ....
    CATCH
    ROLLBACK TRAN
    

    http://msdn.microsoft.com/en-us/library/ms175976.aspx

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-12-19
      • 2016-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多