0

0

Dapper怎么处理数据库的rowversion/timestamp Dapper并发标记列

煙雲

煙雲

发布时间:2025-12-13 18:17:13

|

344人浏览过

|

来源于php中文网

原创

Dapper 不自动处理 rowversion 并发标记,需手动在查询中包含 RowVersion 字段并映射为 byte[],更新时在 WHERE 中显式比对原值,冲突时 rows=0 或 OUTPUT 返回 null,推荐用 OUTPUT 获取新 RowVersion。

dapper怎么处理数据库的rowversion/timestamp dapper并发标记列

Dapper 本身不自动处理 rowversion(SQL Server)或 timestamp(旧称,现为 rowversion)这类并发标记列,但可以很方便地配合它实现乐观并发控制。关键在于:Dapper 不拦截或修改 SQL,你需要自己把 rowversion 字段读出来、传进去、并在 WHERE 条件中显式比对。

读取时带上 rowversion

查询实体时,必须把 rowversion 列包含在 SELECT 中,并映射到实体的 byte[] 或 byte[8] 属性上(SQL Server 的 rowversion 固定 8 字节):

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public byte[] RowVersion { get; set; } // 必须是 byte[],不能是 string 或 long
}

查询示例:

var product = connection.QueryFirstOrDefault(
    "SELECT Id, Name, RowVersion FROM Products WHERE Id = @id", 
    new { id = 123 });

更新时用 WHERE 比对 RowVersion

执行 UPDATE 时,在 WHERE 子句中加入 RowVersion = @originalRowVersion,确保只更新未被他人修改过的行:

var rows = connection.Execute(
    @"UPDATE Products 
      SET Name = @name 
      WHERE Id = @id AND RowVersion = @originalRowVersion",
    new { 
        name = "New Name", 
        id = product.Id, 
        originalRowVersion = product.RowVersion 
    });

如果 rows == 0,说明并发冲突发生(别人已更新,当前 RowVersion 已变),应抛异常或提示重试。

PaperAiBye
PaperAiBye

支持近30多种语言降ai降重,并且支持多种语言免费测句子的ai率,支持英文aigc报告等

下载

更新后重新获取新 RowVersion(可选但推荐)

SQL Server 支持 OUTPUT 子句,可在 UPDATE 后立即返回新生成的 rowversion,避免额外查询:

var updated = connection.QueryFirstOrDefault(
    @"UPDATE Products 
      SET Name = @name 
      OUTPUT INSERTED.Id, INSERTED.Name, INSERTED.RowVersion
      WHERE Id = @id AND RowVersion = @originalRowVersion",
    new { 
        name = "New Name", 
        id = product.Id, 
        originalRowVersion = product.RowVersion 
    });

如果 updated == null,即更新失败(并发冲突);否则 updated.RowVersion 就是最新值,可用于后续操作。

注意点和常见坑

  • 类型必须是 byte[]:用 longstringGuid 映射会出错或值错误
  • 参数名要区分新旧:如 @originalRowVersion@newRowVersion(后者一般不用传,DB 自动生成)
  • 不支持 Dapper 的自动乐观并发(像 EF 的 [ConcurrencyCheck]:一切靠手写 SQL 控制
  • INSERT 无需处理rowversion 是数据库自动生成的,INSERT 语句里不要指定该列

基本上就这些。Dapper 的轻量哲学决定了它不封装并发逻辑,但正因如此,你完全掌控 SQL,能写出高效、明确的乐观并发方案。

相关专题

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

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

679

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的相关内容,可以阅读本专题下面的文章。

346

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数据库的相关内容,可以阅读本专题下面的文章。

675

2024.04.07

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

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

574

2024.04.29

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

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

415

2024.04.29

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

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

27

2026.01.16

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Java 教程
Java 教程

共578课时 | 46.9万人学习

国外Web开发全栈课程全集
国外Web开发全栈课程全集

共12课时 | 1.0万人学习

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

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