运行EF Core迁移能否禁用事务?Postgres枚举迁移报错如何处理
Postgres原生Enum配合Entity Framework迁移的事务问题解答
问题1:是否可以在Entity Framework的迁移功能中关闭事务?
答案是可以,目前有三种主流实现方式:
- 针对单次迁移执行关闭:使用命令行执行迁移时添加
--no-transaction参数,命令示例:dotnet ef database update --no-transaction - 针对指定迁移单独关闭事务:给需要修改枚举的迁移类添加
[Transaction(TransactionBehavior.Suppress)]特性,仅让这一条迁移不使用事务运行 - 全局关闭所有迁移的事务:在DbContext配置中替换默认迁移服务即可实现,该方案仅作为可选列出,不推荐使用
问题2:从最佳实践角度是否推荐关闭事务?
绝对不推荐全局关闭迁移事务,原因如下:
- EF默认给迁移加事务是为了保证迁移的原子性:如果迁移执行到一半失败,事务会自动回滚所有修改,数据库会回到迁移执行前的正常状态,不会出现半完成的损坏状态
- 全局关闭事务后一旦迁移失败,需要手动核对修改了哪些表结构、回滚对应操作,修复成本极高
推荐的问题解决顺序:
- 优先升级Postgres版本到12及以上:Postgres 12版本开始已经支持在事务块中执行
ALTER TYPE ... ADD VALUE操作,不需要修改任何EF配置即可解决问题,是成本最低的解决方案 - 若无法升级PG版本,仅针对修改枚举的单条迁移关闭事务,其余所有迁移保持默认事务开启,将风险降到最低
- 若不想调整事务配置,可以放弃使用Postgres原生Enum类型,改为两种替代方案:
- 将字段映射为.NET枚举,底层存储为int类型,天然支持枚举值新增
- 将字段设置为字符串类型,添加CHECK约束限制取值范围,新增枚举值仅需修改约束即可,不会触发事务相关报错
内容的提问来源于stack exchange,提问作者scottdavidwalker
相关产品推荐
相关产品推荐

