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

本文关键字:安全 EF 访问 列表 工作 中的 Server 进程 SQL | 更新日期: 2023-09-27 18:00:53

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

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

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

下面是一个具有乐观并发(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();
    }
}

此链接将带您了解实体框架的乐观并发的一些设计模式

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

正如您所提到的,我会将InProgress标志与隔离级别为REPEATABLE READ的事务一起使用,这样两个进程就不能读取"空闲"的同一任务。

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

恐怕这里再也没有别的办法了。

您可以使用乐观并发管理,让EF检测冲突,抛出异常,然后进行处理。值得一提的是,使用此解决方案,只有在计算就绪时才会引发冲突。这是一篇关于主题的文章:使用实体框架4.0 处理并发

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

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