【问题标题】:Multiple instances of EF 5.0 DbContext ConcurrencyEF 5.0 DbContext 并发的多个实例
【发布时间】:2014-04-29 05:52:41
【问题描述】:
我正在尝试模拟多个单独的应用程序访问我的数据库的场景。我这样做的方式是创建 10 个不同的线程,这会产生一些并发事务等。每个线程都有一个我的 DbContext 实例。
问题是,DbContexts 不知道其他实例中的更新。所以我的问题是,我如何确保我的 DbContexts 不包含不一致的数据?
【问题讨论】:
标签:
c#
multithreading
entity-framework
dbcontext
【解决方案1】:
如果您使用除 Serializable 之外的任何隔离级别,您将面临某种级别的数据不一致的风险。可序列化在性能方面相当昂贵,并且仅在非常特定的情况下使用。
可序列化
指定以下内容:
语句不能读取已被其他事务修改但尚未提交的数据。
在当前事务完成之前,任何其他事务都不能修改当前事务已读取的数据。
在当前事务完成之前,其他事务不能插入键值落在当前事务中的任何语句读取的键范围内的新行。
范围锁被放置在与事务中执行的每个语句的搜索条件相匹配的键值范围内。这会阻止其他事务更新或插入任何符合当前事务执行的任何语句的行。这意味着如果事务中的任何语句第二次执行,它们将读取相同的行集。范围锁一直保持到事务完成。这是隔离级别中限制性最强的,因为它会锁定整个范围的键并保持锁定直到事务完成。由于并发性较低,因此仅在必要时使用此选项。此选项与在事务中的所有 SELECT 语句中的所有表上设置 HOLDLOCK 的效果相同。
快照隔离还将防止脏读、不可重复读和幻读,但不会阻止线程 1 和线程 2 在重叠时间段内观察不同的数据。
快照
指定事务中任何语句读取的数据将是事务开始时存在的数据的事务一致版本。事务只能识别在事务开始之前提交的数据修改。当前事务开始后其他事务所做的数据修改对于当前事务中执行的语句是不可见的。效果就像事务中的语句获取事务开始时已提交数据的快照一样。
这是一个相当广泛的话题。一个好的起点是
http://technet.microsoft.com/en-us/library/ms189122(v=sql.105).aspx
事务指定了一个隔离级别,该级别定义了一个事务必须与其他事务所做的资源或数据修改隔离的程度。隔离级别是根据允许的并发副作用(例如脏读或幻读)来描述的。
【解决方案2】:
问题是他们缓存了他们调用的数据库表。每当对已缓存的数据库表进行更新时,您都必须创建一个新的 dbContext。
您也可以尝试修改缓存设置以使它们更快超时,因此更新的结果将更快地反映在其他 dbContexts 中(例如,测试启用和禁用延迟加载)。老实说,我从来没有尝试过和他们一起玩。我一直只是制作了一个新的 dbContext,这对我很有用。