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

C#同ReadCommitted事务下操作SQL Server插入后更新无匹配行问题

问题根因分析
  • 自增主键获取逻辑错误:如果InsertRecordInDB方法中通过@@IDENTITY获取插入后的主键值,当目标表存在插入触发器时,@@IDENTITY会返回触发器操作生成的其他表的自增ID,而非当前插入记录的主键,传入错误的ID自然会导致更新匹配不到行。
  • 数据库连接未被事务正确托管:TransactionScope要求所有参与事务的数据库连接必须在TransactionScope的using块内部打开,才会自动纳入当前事务。如果InsertRecordInDB和UpdateRecordInDB内部的连接是在进入事务块之前打开的,两个操作不会在同一个事务中执行,读提交隔离级别下,插入的记录会被其他并发事务删除/修改,导致后续更新找不到行。
  • 事务隐式回滚:TransactionScope默认超时时间为1分钟,如果插入操作执行耗时超过超时阈值,事务会被自动回滚,插入的记录会被撤销,后续更新自然无匹配行。
  • 更新语句存在额外过滤条件:如果UpdateRecordInDB的更新逻辑除了主键匹配外还有其他业务过滤条件(比如WHERE id = @id AND is_valid = 1),刚插入的记录如果被其他并发事务修改了对应字段的值,也会导致更新匹配不到行。
修复方案
  • 修正主键获取逻辑:将插入后获取自增ID的逻辑从@@IDENTITY替换为SCOPE_IDENTITY(),该函数只会返回当前会话、当前作用域生成的最后一个自增ID,不受触发器等外部逻辑影响。
  • 调整连接打开时机:确保InsertRecordInDB、UpdateRecordInDB方法内部的SqlConnection对象的Open()调用,是在TransactionScope的using块执行期间触发的,保证两个操作被纳入同一个事务。
  • 调整事务超时配置:如果业务操作耗时较长,可显式设置事务超时时间,避免隐式回滚:
txOpt.Timeout = TimeSpan.FromMinutes(2); // 可根据实际业务调整最长执行时间
  • 调整隔离级别(可选):如果业务存在并发修改刚插入记录的场景,可将隔离级别从ReadCommitted调整为RepeatableRead,避免当前事务插入的记录被其他事务修改或删除,直到当前事务提交/回滚。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 09:45:02