我们使用代码优先迁移使用Entity Framework 5(和SQL Server 2008 R2)创建了一个数据库。如果我们然后尝试升级到Entity Framework 6.1.0,那么它会在迁移数据库时挂起,直到出现事务超时。
我们在事务内部进行迁移,以确保在出现任何问题时我们可以回滚更改(我们的迁移应用程序也使用Microsoft.SqlServer.Management.Smo.Server进行了一些更改)。如果我们不使用事务,则迁移成功。
在HistoryRepository.GetPendingMigrations()第299行中,我们跟踪了一些查询环境事务之外的迁移历史记录表(使用TransactionScopeOption.Suppress)的代码。
我们已经能够使用最小的测试应用程序重现这一点。类似的东西:
using (var ts = new TransactionScope(TransactionScopeOption.Required))
using (var ctx = new DemoContext())
{
Console.Write(ctx.Entities.Any());
ts.Complete();
}
我们已经在codeplex上提交了bug但尚无反馈:(
修改
在对EF代码进行进一步调查后,我们无法看到如何避免这种情况。具体来说,EF在包装事务中创建一个新的MigrationsHistory表,但尝试在事务外部访问它(使用TransactionScopeOption.Suppress)。当新表被锁定时,这会导致数据库死锁,即使它没有,我们使用的隔离级别也不会显示事务内部的更改。