You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

配置Timestamp乐观并发后有时无法捕获DbUpdateConcurrencyException的原因

问题原因分析

你遇到的偶发无法捕获DbUpdateConcurrencyException的问题,本质是触发乐观并发检测的前提条件没有满足,EF Core基于Timestamp字段的乐观并发逻辑如下:

  1. 查询实体时,EF会将当前数据库中该记录的RowVersion值存入变更跟踪器
  2. 执行SaveChanges时,生成的UPDATE语句会自动拼接WHERE 主键 = 待更新ID AND RowVersion = 初始查询到的值的条件
  3. 只有该UPDATE语句影响行数为0时,EF才会抛出DbUpdateConcurrencyException

偶发不触发异常的常见原因按概率从高到低排列:

  • 操作时序错误:部分测试场景中你先在SSMS执行了UPDATE修改数据,之后程序才运行到var a = context.Students.FirstOrDefault(x => x.Id == 1);这行查询代码。此时查询拿到的RowVersion已经是SSMS修改后的最新值,SaveChanges时WHERE条件可以正常匹配到记录,更新成功不会抛出异常。
  • 调试过程意外刷新了实体的跟踪值:断点暂停期间,如果你在Visual Studio的即时窗口、监视窗口执行了该Student实体的查询操作,或者触发了相关的跟踪查询,会导致变更跟踪器里存储的RowVersion被覆盖为数据库最新值,SaveChanges时不会检测到并发冲突。
  • SSMS的更新操作未生效:测试过程中可能出现PriKey=1的记录被删除、执行SQL时选错了数据库、SQL执行报错等情况,导致VerCol字段没有被更新,EF的UPDATE语句可以正常匹配到记录,自然不会抛出异常。
  • 表字段配置错误(小概率):如果你的Student表是手动创建而非EF Code First自动生成的,可能出现VerCol字段不是rowversion/timestamp类型的问题,普通binary字段修改数据时不会自动更新,自然触发不了并发检测。你可以执行SQL SELECT DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'Student' AND COLUMN_NAME = 'VerCol'确认字段类型。

内容的提问来源于stack exchange,提问作者narojay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 14:45:02