我们正在使用 Playwright 创建集成测试。
我们获得数据库上下文的副本并且
但是开放交易正在阻止测试完成。
public T getContext<T>() where T : DbContext {
T context = Scope.ServiceProvider.GetRequiredService<T>();
Contexts.Add(context);
IDbContextTransaction trans = context.Database.BeginTransaction(System.Data.IsolationLevel.ReadUncommitted);
Transactions.Add(trans); // remember all transactions so we can roll them back later
return context;
}
SUT 每当访问数据库时就会锁定。
更新:我们正在取回 DbContext,但不是 SUT 正在使用的同一实例。
此页面建议使用 UseTransaction,因此我们将其添加到构造函数中。
public DBContextBase(DbContextOptions options) : base(options) {
if (transaction != null) {
Database.UseTransaction(transaction.GetDbTransaction());
}
}
我们确实看到它击中了构造函数并使用事务,但它仍然阻塞第二个上下文。
在启动时,我们尝试通过以下方式强制上下文使用相同的数据库实例:
builder.Services.AddDbContext<DocumentsContext>(options => {
options.UseSqlServer(new SqlConnection(connection));
});
我认为这会起作用。仍然阻塞。
最后,我们选择了快照。
if (File.Exists("c:\\temp\\snapshots\\snapshot01.snp")) {
dbContext.Database.ExecuteSql($"DROP DATABASE Snapshot01");
File.Delete("c:\\temp\\snapshots\\snapshot01.snp");
}
dbContext.Database.ExecuteSql($"CREATE DATABASE Snapshot01 ON(NAME={databasename}, FILENAME= 'c:\\temp\\snapshots\\snapshot01.snp') AS SNAPSHOT OF {databasename}");
----
context.Database.ExecuteSql($"USE MASTER; ALTER DATABASE {databasename} SET Single_User WITH ROLLBACK IMMEDIATE");
context.Database.ExecuteSql($"USE MASTER; RESTORE DATABASE {databasename} FROM DATABASE_SNAPSHOT = 'Snapshot01'");
context.Database.ExecuteSql($"USE MASTER; ALTER DATABASE {databasename} SET Multi_User");