EF Core乐观并发锁怎么用 EF Core RowVersion使用教程

admin 百科 13
EF Core乐观并发锁通过版本校验实现,不阻塞操作,推荐用1766283623标记byte[]字段自动管理;也可用[ConcurrencyCheck]标记业务字段手动维护版本;冲突时抛DbUpdateConcurrencyException,可重载、合并或重试。

EF Core乐观并发锁怎么用 EF Core RowVersion使用教程-第1张图片-佛山资讯网

EF Core 乐观并发锁的核心是“不锁数据,只校验版本”,适合读多写少、冲突概率低的场景。它不阻塞其他读写操作,而是在 SaveChanges() 时通过 WHERE 条件比对版本值来判断数据是否被他人修改过。一旦发现不一致,就抛出异常,由你决定如何处理。

加一个 RowVersion 字段并标记为并发令牌

这是最推荐、最省心的方式,尤其在 SQL Server 中天然支持 rowversion 列。

  • 在实体类中添加 byte[] 类型字段,并用 1766283623 特性标记:

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
    1766283623  // 自动映射为 rowversion(SQL Server)或 bytea(PostgreSQL)
    public byte[] RowVersion { get; set; }
}

登录后复制

  • 或者用 Fluent API 在 OnModelCreating 中配置(效果等同):

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Product>()
        .Property(p => p.RowVersion)
        .IsRowVersion();  // EF Core 会自动设为不可写、每次更新自增
}

登录后复制

注意:该字段无需手动赋值,SQL Server 每次 INSERT/UPDATE 都会自动生成新值;EF Core 会在 UPDATE 语句的 WHERE 子句中自动带上它。

用普通字段做并发检查(灵活但需自己维护)

如果你用的是 MySQL、SQLite 或不想依赖数据库特性,可以用业务字段(如 LastModifiedVersion)当并发令牌。

  • [ConcurrencyCheck] 标记字段:

public class Order
{
    public int Id { get; set; }
    public string OrderNumber { get; set; }
    [ConcurrencyCheck]
    public int Version { get; set; }  // 手动递增
}

登录后复制

  • 或用 Fluent API 配置:

modelBuilder.Entity<Order>()
    .Property(o => o.Version)
    .IsConcurrencyToken();

登录后复制

关键点:你得在每次更新前主动给 Version 加 1(比如 entity.Version++),否则校验永远通过——EF Core 只负责在 SQL 的 WHERE 中加入 AND Version = 原值,不帮你管理值本身。

标签: mysql

发布评论 0条评论)

还木有评论哦,快来抢沙发吧~