我遇到使用Entity Framework TransactionScopes的问题。
在阅读文档并查看多个示例和建议后,我在Web应用程序中的许多查询中实现了事务范围。我在这里遇到的问题与隔离级别有关。我希望TransactionScope中的每个查询都是ReadUncommited,但由于某种原因,只有第一个查询需要隔离级别(READ UNCOMMITED),但所有后续查询都恢复为READ COMMITED。这些查询读取了大量数据,我不介意脏读。
这是我的EF TransactionScope和Context(非常基本):
var transactionOptions = new TransactionOptions { IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted };
using (var transactionScope = new TransactionScope(TransactionScopeOption.Required, transactionOptions, TransactionScopeAsyncFlowOption.Enabled))
{
using (var db = new Context())
{
//db.Database.ExecuteSqlCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;");
//var SessionID = await db.Database.SqlQuery<short>("SELECT @@SPID").FirstOrDefaultAsync();
//db.Database.Log = s => System.Diagnostics.Debug.WriteLine(s);
//QUERY1
var list1= await db.Table1.Include(x => x.ExternalProperty).Where(x => x.Created >= sevenDaysAgo).ToListAsync();
//QUERY2
var list2 = await db.Table1.Include(x => x.ExternalProperty).Where(x => x.Created >= fourteenDaysAgo && x.Created <= eightDaysAgo).ToListAsync();
//... Doing more stuff here
transactionScope.Complete();
}
}
QUERY 1使用READ UNCOMMITED执行,而由于某种原因,QUERY 2使用READ COMMITED执行。我错过了什么吗?因为在我的理解中,这不应该发生,因为两个查询都使用相同的TransactionScope。
我使用await db.Database.SqlQuery<short>("SELECT @@SPID").FirstOrDefaultAsync()
来获取上下文保留的会话ID,以确保使用相同的会话。
我还尝试使用db.Database.ExecuteSqlCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;");
手动设置隔离级别,这导致了相同的行为。
我一直在搜索,几乎所有答案都建议使用上面的代码。例如:THIS ANSWER
为什么会发生这种情况,特别是因为TransactionScope尚未完成?
由于
答案 0 :(得分:0)
除非有人有更好的答案,否则这就解决了我的问题。
我必须在transactionscope中手动打开和关闭连接,或者命令停止EF上下文在每次查询之间将连接返回到池。
我使用了db.Database.Connection.Open();
和db.Database.Connection.Close();
请注意,这会在处理上下文之前保持连接处于活动状态。请注意,因为它可能不适合您的场景。