使用SqlPackage.exe回滚失败的DACPAC

时间:2016-09-26 15:58:06

标签: sql deployment dacpac sqlpackage

我经常使用EF迁移来部署数据库,无论是从头开始还是为了进化。我目前正在研究另一个使用DACPAC的团队项目,这个项目看起来一样好,直到今天。今天,我在缺少它的表中添加了一个唯一键约束,正如您可能想象的那样,它会爆炸,导致通过sqlpackage.exe进行DACPAC部署失败。

我现在意识到失败绝不会回滚,所以现在我有一个处于部分转换状态的数据库,因为我有一个预部署脚本,指的是在预部署后删除的列脚本第一次运行,状态现在让我无法再次运行dacpac,因为它因此而失败。

我错误地认为,sqlpackage.exe将在事务中包装部署并在失败时将其回滚。然后在实现我的错误时,又错误地假设我错过了某个地方的旗帜。

任何人都可以告诉我如何在不破坏数据库的情况下安全地运行一个......

2 个答案:

答案 0 :(得分:2)

您可以使用/ p:IncludeTransactionalScripts = true让SqlPackage.exe将主模式更改操作作为单个事务执行。但请注意,部署前和部署后脚本不包含在该事务逻辑中。建议的做法是以可以安全地重新执行它们(即作为幂等T-SQL)的方式编写部署前和部署脚本。

答案 1 :(得分:0)

遇到同样的问题,除了Steven所写的内容,我在Pre& amp; amp; amp; amp; amp; amp; amp; amp; amp; amp; amp; amp;发布部署脚本,以便在发生故障时回滚脚本:(您可以取消注释IF EXISTS部分以进行进一步的验证/测试)

SET IMPLICIT_TRANSACTIONS ON    --By default it is OFF

BEGIN TRY
    /*
    IF (EXISTS (SELECT * 
                     FROM INFORMATION_SCHEMA.TABLES 
                     WHERE TABLE_SCHEMA = 'DW' 
                     AND  TABLE_NAME = 'TBL_Users'))
    BEGIN
    */
        DROP TABLE DW.TBL_Users
        DROP TABLE DW.NOT_EXIST_TABLE
    --END
END TRY

BEGIN CATCH
    ROLLBACK TRANSACTION;
    DECLARE @ERROR_MESSAGE  VARCHAR(2000);
    SET @ERROR_MESSAGE = CONCAT('Pre deployment script failed failed. ', ERROR_MESSAGE());
    THROW 51000, @ERROR_MESSAGE, 1
END CATCH

COMMIT TRANSACTION;
SET IMPLICIT_TRANSACTIONS OFF --Set back to OFF default
相关问题