多个进程安全地使用SQL Server中的EF访问工作列表

时间:2014-04-30 14:24:33

标签: c# sql-server entity-framework

我在SQL服务器中有一个表,其中包含一些不断添加的小任务列表。使用实体框架的进程会查询未完成任务的列表任务,选择一个,完成任务并更新任务状态。我想在多台机器上运行多个进程,以便完成任务,但是存在两个进程可能从表中选择相同任务的风险,这会导致问题。我不能使用并发原语,因为任务使用者在不同的机器上运行不同的进程。是否有可接受的模式如何做到这一点?我想我需要做一些事情,比如尝试将任务设置为"正在进行中"然后确保没有其他进程做同样的事情,但我想知道是否有一种直接的方法来使用实体框架。

3 个答案:

答案 0 :(得分:0)

您可以向表中添加timestamp / rowversion类型的列,并设置表配置,让实体框架知道此列将用于乐观并发。此列的工作方式是每次对数据库中的行进行更新时递增。当您的某个进程具有该实体的实例时,它在获取时具有timestamp列的值。当Entity Framework尝试更新数据库中的这一行时,它会对where子句附加一个检查,该子句指定时间戳为从数据库中获取实体时的值。如果值不匹配,则由于行已更改,因此将抛出OptimisticConcurrencyException。

以下是具有乐观并发性的实体(Store-Wins)的设置示例

public class Foo 
{
    public int FooId { get; set; }

    // ...Other instance members

    public byte[] ConcurrencyCheck { get; private set; }
}

public class FooConfiguration : EntityTypeConfiguration<Foo>
{
    public FooConfiguration()
    {
        Property(t => t.ConcurrencyCheck)
            .IsRowVersion();
    }
}

此链接将带您进入使用Entity Framework

的乐观并发的一些设计模式

http://msdn.microsoft.com/en-us/data/jj592904.aspx

答案 1 :(得分:0)

我会使用InProgress标志,就像你提到的具有隔离级别REPEATABLE READ的事务一样,这样两个进程就无法读取与#34; free&#34;相同的任务。

您可以使用EF本机支持的TransactionScope类。

我担心在这里没有什么比这更好的了。

答案 2 :(得分:0)

您可以使用乐观并发管理,让EF检测冲突,抛出异常然后处理它。值得一提的是,使用此解决方案,只有在计算准备就绪时才会引发冲突。 以下是有关该主题的文章:Handling Concurrency with the Entity Framework 4.0

您还可以使用悲观并发管理并在初始化任务时锁定所选行以进行更新。 EF不支持悲观并发管理,也可以是数据库引擎特定的。

您还可以实施自定义&#34;锁定机制&#34;。如您所建议,您可以通过在单独的字段中跟踪任务的状态来执行此操作。防止多个进程进入&#34;进行中&#34; state,您可以使用乐观并发管理。此解决方案是本机乐观并发处理的升级版本,因为在初始化任务以在客户端上进行计算之前会引发冲突。