0

0

EF Core如何配置并发令牌 EF Core IsConcurrencyToken方法

幻夢星雲

幻夢星雲

发布时间:2025-12-16 10:45:08

|

283人浏览过

|

来源于php中文网

原创

EF Core 配置并发令牌的核心目标是启用乐观并发控制以防止“丢失更新”,通过 SaveChanges() 时比对原始值,不一致则抛出 DbUpdateConcurrencyException;推荐使用 [Timestamp] 注解(SQL Server 支持 rowversion)或 Fluent API 的 IsRowVersion()(数据库自动管理),若用 IsConcurrencyToken() 则需手动维护字段值,并必须捕获异常处理。

ef core如何配置并发令牌 ef core isconcurrencytoken方法

EF Core 配置并发令牌的核心目标是启用乐观并发控制,防止“丢失更新”——即多个用户同时读取同一行、各自修改后保存,后保存者无意中覆盖前者的更改。关键不在于“加锁”,而是在 SaveChanges() 时自动比对原始值,不一致就抛出 DbUpdateConcurrencyException,由你决定如何响应。

两种主流配置方式:数据注解 vs Fluent API

你可以任选其一,推荐 Fluent API(更集中、可测试、不污染实体类);但 [Timestamp] 注解因数据库原生支持,仍是首选。

  • [Timestamp](最推荐):适用于 SQL Server 等支持 rowversion 的数据库。EF Core 会自动映射为 byte[] 类型列,每次更新行时数据库自动生成新值,无需手动维护。
    public class Product {
    public int Id { get; set; }
    public string Name { get; set; }
    [Timestamp]
    public byte[] RowVersion { get; set; }
    }
  • [ConcurrencyCheck]:标记任意属性(如 LastModifiedStatus),适合业务语义明确的字段。但需确保该字段在每次更新时被正确赋值(比如手动设置 DateTime.UtcNow),否则检测失效。
  • 用 Fluent API 的 IsConcurrencyToken():灵活度最高,可配置普通字段或导航属性,也支持链式调用。例如:
    modelBuilder.Entity()
    .Property(o => o.Version)
    .IsConcurrencyToken();

    注意:若字段本身不是数据库自增/自动更新类型(如 intDateTime),你必须在业务逻辑中主动更新它的值,否则并发检测形同虚设。

IsConcurrencyToken() 和 IsRowVersion() 的区别

IsConcurrencyToken() 是通用方法,把任意属性设为并发检查点,但值要靠代码维护;IsRowVersion() 是专用于 rowversion / timestamp 列的快捷方式,仅 SQL Server 支持,数据库自动管理值,更可靠。

  • .IsRowVersion() 时,EF Core 迁移会生成带 rowVersion: true 的列定义,且该列不可写入(只读);
  • .IsConcurrencyToken() 配置 DateTime 字段,则迁移只是普通列,你得确保每次 SaveChanges() 前都设置了新时间戳。

配置后必须处理异常,否则并发冲突直接崩掉

配置完令牌只是第一步。真正起作用的是捕获 DbUpdateConcurrencyException 并做合理应对,常见策略有:

花生AI
花生AI

B站推出的AI视频创作工具

下载
  • 重载最新数据,提示用户“他人已修改”,让用户选择是否覆盖;
  • 自动合并:保留数据库中的部分字段(如审核状态),应用用户修改的字段(如备注);
  • 乐观重试:用 entry.OriginalValues.SetValues(databaseValues) 同步到最新快照,再调用 SaveChanges() 重试(适合幂等操作)。

验证是否生效的小技巧

写个简单测试:查出一条记录 → 手动用 SQL 修改数据库里对应的 RowVersion 或并发字段 → 再调用 SaveChanges()。如果抛出 DbUpdateConcurrencyException,说明配置成功。

基本上就这些。不复杂但容易忽略的是:配了令牌却没处理异常,或者用了 IsConcurrencyToken() 却忘了更新字段值——这两点会让乐观锁完全失效。

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

682

2023.10.12

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

320

2023.10.27

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

347

2024.02.23

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

1095

2024.03.06

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

357

2024.03.06

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

676

2024.04.07

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

575

2024.04.29

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

416

2024.04.29

高德地图升级方法汇总
高德地图升级方法汇总

本专题整合了高德地图升级相关教程,阅读专题下面的文章了解更多详细内容。

72

2026.01.16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PHP新手语法线上课程教学
PHP新手语法线上课程教学

共13课时 | 0.9万人学习

光速学会docker容器
光速学会docker容器

共33课时 | 1.9万人学习

时间管理,自律给我自由
时间管理,自律给我自由

共5课时 | 0.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号