4

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

我现在意识到的是,故障绝不会回滚,所以现在我有一个处于部分转换状态的数据库,并且因为我有一个预部署脚本引用在预部署脚本运行后删除的列第一次,现在的状态是我不能再次运行 dacpac,因为它会因为这个原因而失败。

我错误地认为 sqlpackage.exe 会将部署包装在事务中并在失败时将其回滚。然后在意识到我的错误时,再次错误地假设我在某个地方错过了一个标志。

谁能告诉我如何在不破坏数据库的情况下安全地运行...

4

2 回答 2

6

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

于 2016-09-26T22:42:06.293 回答
1

遇到同样的问题,除了 Steven 写的内容之外,我在 Pre & Post 部署脚本中放置了一个包装器,在失败的情况下将回滚脚本:(您可以取消注释 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
于 2018-05-23T06:25:10.327 回答