【发布时间】:2015-03-05 14:50:57
【问题描述】:
我一直在阅读 Microsoft 模式与实践小组 (Data Access for Highly-Scalable Solutions: Using SQL, NoSQL, and Polyglot Persistence) 的文档。
在第 3 章的 "Retrieving Data from the SQL Server Database" 部分,作者讨论了使用实体框架从数据库加载实体。这是他们的一些示例代码:
using (var context = new PersonContext())
{
Person person = null;
using (var transactionScope = this.GetTransactionScope())
{
person = context.Persons
.Include(p => p.Addresses)
.Include(p => p.CreditCards)
.Include(p => p.EmailAddresses)
.Include(p => p.Password)
.SingleOrDefault(p => p.BusinessEntityId == personId);
transactionScope.Complete();
}
// etc...
}
注意通过GetTransactionScope 方法使用自定义事务范围,在它们的基本上下文类中实现,如下所示:
public abstract class BaseRepository
{
private static TransactionOptions transactionOptions = new TransactionOptions()
{
IsolationLevel = IsolationLevel.ReadCommitted
};
protected virtual TransactionScope GetTransactionScope()
{
return new TransactionScope(TransactionScopeOption.Required, transactionOptions);
}
}
MSDN 上的Working with Transactions (EF6 Onwards) 声明:
在所有版本的 Entity Framework 中,每当您执行 SaveChanges() 以在数据库上插入、更新或删除时,框架都会将该操作包装在事务中 [...] 事务的隔离级别是任何隔离级别数据库提供程序考虑其默认设置。例如,默认情况下,在 SQL Server 上,这是 READ COMMITTED。 实体框架不会将查询包装在事务中。此默认功能适用于很多用户
大胆的强调是我的。
我的问题:使用 Entity Framework 时,使用如上所示的 TransactionScope 是否过度,特别是对于数据读取?
(发布后我意识到这个问题的答案可能有点基于意见,对此感到抱歉。)
【问题讨论】:
-
有了这个
isolationLevel,如果事务只包含读操作,这个代码就有点过分了。但是如果isolationLevel是ReadUncommited,则这段代码将允许您读取脏行(尚未提交)。 -
如果它不能用于商业目的,你应该避免使用事务范围。这是为了避免死锁和性能问题。
标签: c# entity-framework design-patterns