繁体   English   中英

如何使用 EF 6 实现乐观并发锁?

[英]How to implement optimistic concurrency lock with EF 6?

我有一个关于 SQL Server、实体框架和 Web API 的问题。

我需要管理一个序列号数据库。 为此,我在 SQL Server 中创建了一个序列表。 我首先使用 EF6 代码。

public class Sequence : ITrackingDate
{
    [Key]
    public string Name { get; set; }
    public long CurrentValue { get; set; }
    public long Increment { get; set; }
    public long MinimumValue { get; set; }
    public long MaximumValue { get; set; }
    public bool IsCycling { get; set; }
    public DateTime CreateDate { get; set; }
    public DateTime ModifyDate { get; set; }
}

ITrackingDate 用于在 EF 的 DataContext 中更新我的 CreateDate 和 ModifyDate。 我覆盖了 SaveChanges。

这应该作为一个序列工作(就像在 SQL Server 2012 中一样),但我想在特定的数据库中自己管理它,因为我将不得不创建许多序列,而且其中大多数将带来比我们只有在基本序列中拥有的更多的数据系统。 我需要的一项功能是可以按范围更新序列。

var serial = context.Sequences.SingleOrDefault(y => y.Name == serialName);
                var firstValue = serial.CurrentValue + 1;
                var lastValue = serial.CurrentValue + range;
                serial.CurrentValue = lastValue;
                context.SaveChanges();

此代码位于 Web 服务后面,因此可能有两个请求同时执行此部分代码并返回相同的值。 这是需要防止的。

所以 SaveChanges() 方法还必须检查我正在保存的内容在 read() 之后没有被另一个线程更新。

这当然是有可能做到安全的。 首先要注意,并发访问必须一个接一个。 乐观并发在这里无济于事。

解决这个问题有两种基本策略:

  1. 使用可RepeatableRead事务。 这将导致死锁,您可以通过重试来解决。 重试是安全的,并保证取得进展。
  2. U 锁定该行作为您事务中的第一个操作。 实体框架无法直接执行此操作,因此您需要为此手动执行 SQL。 正确的锁定提示是UPDLOCK, HOLDLOCK, ROWLOCK

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM