我经常使用EF迁移来部署数据库,无论是从头开始还是为了进化。我目前正在研究另一个使用DACPAC的团队项目,这个项目看起来一样好,直到今天。今天,我在缺少它的表中添加了一个唯一键约束,正如您可能想象的那样,它会爆炸,导致通过sqlpackage.exe进行DACPAC部署失败。
我现在意识到失败绝不会回滚,所以现在我有一个处于部分转换状态的数据库,因为我有一个预部署脚本,指的是在预部署后删除的列脚本第一次运行,状态现在让我无法再次运行dacpac,因为它因此而失败。
我错误地认为,sqlpackage.exe将在事务中包装部署并在失败时将其回滚。然后在实现我的错误时,又错误地假设我错过了某个地方的旗帜。
任何人都可以告诉我如何在不破坏数据库的情况下安全地运行一个......
答案 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