当前位置: 首页 > article >正文

【并发控制、更新、版本控制】.NET开源ORM框架 SqlSugar 系列

系列文章目录

🎀🎀🎀 .NET开源 ORM 框架 SqlSugar 系列 🎀🎀🎀


文章目录

  • 系列文章目录
  • 一、并发累计(累加)
    • 1.1 单条批量累计+
    • 1.2 批量更新并且字段+1
    • 1.3 批量更新并且字段+list中对应的值
  • 二、防止提交覆盖,重复提交(乐观锁)
    • 2.1 不依赖库同步 (新功能)
    • 2.2 依赖库同步(老功能)
    • 2.3 一对多提交
  • 三、悲观锁的用法
    • 3.1 悲观锁等待模式
    • 3.2 悲观锁排它模式
    • 在这里插入图片描述
  • 🎀🎀🎀 .NET开源 ORM 框架 SqlSugar 系列 🎀🎀🎀


一、并发累计(累加)

1.1 单条批量累计+

比如要扣钱什么的,或者数字叠加,这种就需要通过 set 字段=段字段+1 这种方处理。

//正确写法:安全的字段累计
var result= db.Updateable<Student>().SetColumns(it => it.Num== it.Num+1).Where(it => it.Id == 1).ExecuteCommand();
//sql: num=num+1 //错误写法: 在程序中计算是不安全的
var num=data.num+1
var result= db.Updateable<Student>().SetColumns(it => it.Num== num).Where(it => it.Id == 1).ExecuteCommand();
//sql:  num=值

🎯注意:这种更新方式只适合明确主键的更新,条件形态的建议用下面的锁。

1.2 批量更新并且字段+1

 var result67 =db.Updateable(updateObjs)//批量更新单独处理num列 set num=num+1.PublicSetColumns(it => it.Num, it => it.Num+ 1).ExecuteCommand();

1.3 批量更新并且字段+list中对应的值

   db.Updateable(list)PublicSetColumns(it => it.Price, "+") //set price=price+list[i].price.ExecuteCommand();

二、防止提交覆盖,重复提交(乐观锁)

📌使用乐观锁需要满足2个条件:

  1. 用户要打开编辑界面,然将数据绑定到编辑界面
  2. 用户在界面填写完在点修改保存

💯原理: 打开编辑框太久别人已经修改了这条记录,我在提交就可能把别人更新数据清空掉,我们需要一个时间字段去和数据库中的Version比对

🎇重现步骤:开2个浏览器 ,编辑同一条记录, A浏览器先保存,然后B浏览器在保存就能重现

因为是同一条记录本身并不存在并发,因为编辑界面打开一天也不会刷新数据,点保存一样覆盖

2.1 不依赖库同步 (新功能)

新项目推荐用新功能,使用方便有问题及时沟通

    public class ULockEntity{[SqlSugar.SugarColumn(IsPrimaryKey = true, IsIdentity = true)]public int Id { get; set; }public string Name { get; set; }[SqlSugar.SugarColumn(IsEnableUpdateVersionValidation = true)]//标识版本字段public long Ver { get; set; } //支持Guid long string DateTime (不推荐DateTime 时间有精度问题)//推荐用 string guid  (使用long要序列化成strting不然前端精度丢失)}//注意:只能是实体更新不能是集合更新//【用法1:不扔错】 Ver与数据库字段不同不报错返回0var rows = db.Updateable(new ULockEntity(){Id = id,Name = "newname",Ver = 1551128313597136896//版本字段会自动更新}).ExecuteCommandWithOptLock(); //【用法2:扔出错误】Ver与数据库字段不同直接扔错出误var rows = db.Updateable(new ULockEntity(){Id = id,Name = "newname",Ver = 1551128313597136896  //版本字段会自动更新}).ExecuteCommandWithOptLock(true); //加上true就会扔出错误//try { ... }catch(VersionExceptions ex){...}//底层 throw new VersionExceptions/*********完整测试用例*********///添加测试数据var db = NewUnitTest.Db;db.CodeFirst.InitTables<ULockEntity>();db.DbMaintenance.TruncateTable<ULockEntity>();//第一次插入ver=0var id = db.Insertable(new ULockEntity(){Name = "oldName" ,Ver=0}).ExecuteReturnIdentity();//开始用例var rows= db.Updateable(new ULockEntity(){Id = id,Name = "newname",Ver = 0  //会自动更新版本字段更新后数据库将不在是0}).ExecuteCommandWithOptLock();  //rows=1 因为数据库ver是0你传的也是0var rows= db.Updateable(new ULockEntity(){Id = id,Name = "newname2",Ver = 0}).ExecuteCommandWithOptLock();   //rows=0  失败:数据库ver不等于0

2.2 依赖库同步(老功能)

例如:SqlServer 中的时间戳类型的字段,会在这条记录变更后会自动更新,如果没这种机质的字段你也可以用触发器实现这种机质

有这种机质我们只要打个特性就能实现并发控制,代码如下:

数据库数据库实体
SQLSERVERtimestamp默认自动更新)byte[]
其他数据库timestamp(需要配置自动更新)DateTime

public class StudentVersion    
{[SugarColumn(IsPrimaryKey =true,IsIdentity =true)]    public int Id { get; set; }    public string Name { get; set; }    public DateTime CreateTime { get; set; }    [SqlSugar.SugarColumn(IsEnableUpdateVersionValidation = true,//标识版本字段 IsOnlyIgnoreInsert=true,//禁止插入IsOnlyIgnoreUpdate=true,//禁止更新ColumnDataType="timestamp" //时间戳类型,有些库需要配置或者有差异)]   // SqServer byte[] 其它数据库用 DateTime                        public byte[]  Timestamp { get; set; } 
}    
db.Updateable(data).IsEnableUpdateVersionValidation().ExecuteCommand();//更新的时候启用验证

原理:

 //查询这条记录var data = db.Queryable<StudentVersion>().InSingle(id);//成功 (data.Timestamp等于数据库中的 Timestamp字段)db.Updateable(data).IsEnableUpdateVersionValidation().ExecuteCommand();//执行后数据库Timestamp更新//失败 (data.Timestamp不等于数据库中的 Timestamp字段)db.Updateable(data).IsEnableUpdateVersionValidation().ExecuteCommand();

如何知道是并发错误,还是其他错误

//底层代码 
throw new VersionExceptions //捕获异常的时候只要是 VersionExceptions 那就是并发错误

2.3 一对多提交

只处理主表数据就行了,从表不需要考虑,因为是一起提交。

三、悲观锁的用法

悲观锁适合用于 读取和插入在同一个步骤下的操作,并且禁止2个请求同时操作

3.1 悲观锁等待模式

🎯定义:2个相同的业务代码 同时执行时必须等待 第一个执行成功后执行。

主键查询一般是行锁,如果非主键可以会变成表锁。


db.BeginTran();
//查询条件记录后锁表
var data=db.Queryable<Order>().TranLock(DbLockType.Wait).Where(it=>it.Id==1).ToList();//返回条数尽量最少尽量主键
//插入、更新等操作
.......
db.CommitTran();//异常要加上
db.RollBackTran();

3.2 悲观锁排它模式

🎯定义:2个相同的业务代码 同时执行时只会生效一个,其它都扔出错误。

db.BeginTran();
//查询条件记录后锁表
var data = db.Queryable<Order>().TranLock(DbLockType.Error).Where(it=>it.Name=="a").ToList();//返回条数尽量最少 for update UPDLOCK
//插入、更新等操作 
.......
db.CommitTran();//异常要加上
db.RollBackTran();

测试代码:

用的来验证是否扔出异常


for (int i = 0; i < 10; i++)
{Task.Run(() =>{var db = GetInstance();//用的sqlsugarclient保证db线程安全每次New一下try{db.BeginTran();var getAll = db.Queryable<Order>().TranLock(DbLockType.Error).ToList();System.Threading.Thread.Sleep(1000);db.CommitTran();Console.WriteLine("成功");}catch (Exception ex){db.RollBackTran();Console.WriteLine("失败");}});
}

在这里插入图片描述

🎀🎀🎀 .NET开源 ORM 框架 SqlSugar 系列 🎀🎀🎀

【开篇】.NET开源 ORM 框架 SqlSugar 系列
【入门必看】.NET开源 ORM 框架 SqlSugar 系列
【实体配置】.NET开源 ORM 框架 SqlSugar 系列
【Db First】.NET开源 ORM 框架 SqlSugar 系列
【Code First】.NET开源 ORM 框架 SqlSugar 系列
【数据事务】.NET开源 ORM 框架 SqlSugar 系列
【连接池】.NET开源 ORM 框架 SqlSugar 系列
【查询目录】.NET开源 ORM 框架 SqlSugar 系列
【查询基础】.NET开源 ORM 框架 SqlSugar 系列
【排序用法】.NET开源 ORM 框架 SqlSugar 系列
【分组去重】.NET开源 ORM 框架 SqlSugar 系列
【联表查询】.NET开源 ORM 框架 SqlSugar 系列
【导航查询】.NET开源 ORM 框架 SqlSugar 系列
【子查询】.NET开源 ORM 框架 SqlSugar 系列
【嵌套查询】.NET开源 ORM 框架 SqlSugar 系列
【配置查询】.NET开源 ORM 框架 SqlSugar 系列
【并集查询】.NET开源 ORM 框架 SqlSugar 系列
【树型查询】.NET开源 ORM 框架 SqlSugar 系列
【表格查询】.NET开源 ORM 框架 SqlSugar 系列
【动态表达式】.NET开源 ORM 框架 SqlSugar 系列
【查询函数】.NET开源ORM框架 SqlSugar 系列
【过滤器】.NET开源 ORM 框架 SqlSugar 系列
【跨库查询、多库查询】.NET开源 ORM 框架
​【报表查询】.NET开源ORM框架 SqlSugar 系列
【Where语法全解密】.NET开源ORM框架 SqlSugar 系列
【Select 语法全解密】.NET开源ORM框架 SqlSugar 系列
【查询返回结果类型】.NET开源ORM框架 SqlSugar 系列
【insert 插入数据语法合集】.NET开源ORM框架 SqlSugar 系列
【SqlSugar雪花ID常见问题】.NET开源ORM框架 SqlSugar 系列
【update 更新数据语法合集】.NET开源ORM框架 SqlSugar 系列


在这里插入图片描述

相关文章:

【并发控制、更新、版本控制】.NET开源ORM框架 SqlSugar 系列

系列文章目录 &#x1f380;&#x1f380;&#x1f380; .NET开源 ORM 框架 SqlSugar 系列 &#x1f380;&#x1f380;&#x1f380; 文章目录 系列文章目录一、并发累计&#xff08;累加&#xff09;1.1 单条批量累计1.2 批量更新并且字段11.3 批量更新并且字段list中对应的…...

DeepSeek-R1本地搭建

1. 前言 现在deepseek火上天了&#xff0c;因为各种应用场景,加上DeepSeek一直网络异常&#xff0c;所以本地部署Deepseek成为大家的另一种选择。 目前网络上面关于DeepSeek的部署方式有很多&#xff0c;但是太麻烦了&#xff0c;本文是一篇极为简单的DeepSeek本地部署方式&…...

查出 product 表中所有 detail 字段包含 xxx 的完整记录

您可以使用以下 SQL 查询语句来查出 product 表中所有 detail 字段包含 oss.kxlist.com 的完整记录&#xff1a; SELECT * FROM product WHERE INSTR(detail, oss.kxlist.com) > 0;下面是detail字段包含的完整内容 <p><img style"max-width:100%;" src…...

python技术可以开发的应用类型有哪些?

Python 是一种功能强大且灵活的编程语言,广泛应用于多个领域。以下是一些常见的 Python 应用程序开发领域及其具体案例: 1. Web 开发 Python 提供了多个流行的 Web 框架,如 Django 和 Flask,用于构建 Web 应用程序。 示例:使用 Flask 构建简单的 Web 应用 Python复制 …...

Redis存储⑥Redis五大数据类型之 Zset

目录 1. Zset 有序集合 1.1 Zset 有序集合常见命令 zadd zcard zcount zrange zrevrange zrangebyscore&#xff08;弃用&#xff09; zpopmax bzpopmax zpopmin bzpopmin zrank zrevrank zscore zrem zremrangebyrank zremrangebyscore zincrby 1.2 Zset有…...

Kafka 读写示例

一、概述 Kafka 是一款流行的分布式消息队列系统,具有高吞吐量、可扩展性和持久性等优点。本文将介绍如何使用 Kafka 进行消息的生产和消费。 二、Kafka 生产者 1. 生产者配置 以下是一些常用的 Kafka 生产者配置参数: 参数描述bootstrap.serversKafka 集群的地址,用于生…...

将Excel中的图片保存下载并导出

目录 效果演示 注意事项 核心代码 有需要将excel中的图片解析出来保存到本地的小伙子们看过来&#xff01;&#xff01;&#xff01; 效果演示 注意事项 仅支持xlsx格式&#xff1a;此方法适用于Office 2007及以上版本的.xlsx文件&#xff0c;旧版.xls格式无法使用。 图片名…...

SQL注入之布尔和时间盲注,sqli-labs

实验环境&#xff1a; sqli-labs&#xff0c;小皮面板搭建&#xff0c;edge浏览器 apache&#xff1a;2.4.39&#xff0c;MySQL&#xff1a;5.7 PHP&#xff1a;5.39 Python&#xff08;pycharm2023&#xff09;:3 less-8 布尔盲注&#xff1a; 1.我这里是采用最简单的直接采…...

Ubuntu 22.04完整安装Xinference及解决依赖报错

注&#xff1a;文中使用的环境为Ubuntu 22.04 LTS CUDA 12.4.1 1、创建conda环境 conda create -n xinference python3.11 -y conda activate xinference2、安装Xinference pip install "xinference[all]"3、解决报错 Pytorch报错 根据Pytorch安装指引进行安装…...

基于云计算、大数据与YOLO设计的火灾/火焰目标检测

摘要&#xff1a;本研究针对火灾早期预警检测需求&#xff0c;采用在Kaggle平台获取数据、采用云计算部署的方式&#xff0c;以YOLO11构建模型&#xff0c;使用云计算服务器训练模型。经训练&#xff0c;box loss从约3.5降至1.0&#xff0c;cls loss从约4.0降至1.0&#xff0c;…...

C与C++的区别,类型转换,引用

1.从C到C 语言的区别 C语言 编译性语言 面向过程语言灵活 移植性好 效率高shell 解释性语言 面向过程语言Linux运维C 编译性语言 面向对象面向对象语言效率最高的 应用领域&#xff1a;系统开发(APP开发&#xff0c;服务器开发)&#xff0c;引擎开发&#xff0c;游戏开发&…...

YOLO自定义数据集实现K折交叉验证——K-Fold Cross Validation

实现K折交叉验证&#xff08;K-Fold Cross Validation&#xff09;对于YOLO&#xff08;You Only Look Once&#xff09;自定义数据集的目标检测任务可以显著提升模型的可靠性和泛化能力。 1. 数据集准备 首先&#xff0c;你需要确保你的数据集符合YOLO的格式&#xff0c;具体…...

刚体的力+射线相关知识点+延迟函数

AddForceAtPosition cube0.AddForceAtPosition(Vector3.forward*5,target.transform.position); force:给cube0一个力&#xff0c;控制cube0的移动&#xff1b; position&#xff1a;cube0和所给点的连线力得大小&#xff0c;这个力跟移动方向有夹角&#xff0c;会造成cube0…...

集合家族详情

一、Java集合框架全景图 1.1 核心接口层次结构 graph TDA[Iterable] --> B[Collection]B --> C1[List]B --> C2[Set]B --> C3[Queue]C1 --> D1[ArrayList]C1 --> D2[LinkedList]C2 --> E1[HashSet]C2 --> E2[TreeSet]C3 --> F1[PriorityQueue]G[M…...

go语言简单快速的按顺序遍历kv结构(map)

文章目录 需求描述用map实现按照map的key排序用二维切片实现用结构体实现 需求描述 在go语言中&#xff0c;如果需要对map遍历&#xff0c;每次输出的顺序是不固定的&#xff0c;可以考虑存储为二维切片或结构体。 假设现在需要在页面的下拉菜单中展示一些基础的选项&#xff…...

【竞技宝】LOL-LPL:EDG3-0零封LNG

北京时间2月12日,英雄联盟LPL2025正在如火如荼的进行之中,昨日迎来LNG对阵EDG,以下是本场比赛的详细战报。 第一局: EDG:杰斯、赵信、维克托、女枪、芮尔 LNG:猴子、猪妹、飞机、韦鲁斯、布隆 首局比赛,EDG在蓝色方,LNG在红色方。阵容方面,EDG点出了杰斯、赵信、维克托、女枪…...

在fedora41中安装钉钉dingtalk_7.6.25.4122001_amd64

在Fedora-Workstation-Live-x86_64-41-1.4中安装钉钉dingtalk_7.6.25.4122001_amd64.deb 到官网下载钉钉Linux客户端com.alibabainc.dingtalk_7.6.25.4122001_amd64.deb https://page.dingtalk.com/wow/z/dingtalk/simple/ddhomedownload#/ 一、直接使用dpkg命令安装deb包报错…...

看期货用的指标,可以提示买卖点和K线转折变颜色的主图指标源码下载

A:MA(CLOSE,17)ABS(MA(CLOSE,17)-REF(MA(CLOSE,17),1)); B:MA(CLOSE,17)MA(CLOSE,17)-REF(MA(CLOSE,17),1); 分界线:IF(MA(CLOSE,17)<B,B,MA(CLOSE,17)),COLORFF00FF,LINETHICK2; 操作线:分界线-(EMA(C,3)-分界线),COLOR00FFFF,LINETHICK2; GUP:MA(C,5),COLORWHITE,LINE…...

【PS 2022】Adobe Genuine Service Alert 弹出

电脑总是弹出Adobe Genuine Service Alert弹窗 1. 不关掉弹窗并打开任务管理器&#xff0c;找到Adobe Genuine Service Alert&#xff0c;并右键进入文件所在位置 2 在任务管理器中结束进程并将文件夹中的 .exe 文件都使用空文档替换掉 3. 打开PS不弹出弹窗&#xff0c;解决&a…...

计算机网络知识速记:HTTP1.0和HTTP1.1

计算机网络知识速记&#xff1a;HTTP1.0和HTTP1.1 1. 基本概念 1.1 HTTP1.0 HTTP1.0是1996年发布的第一个正式版本&#xff0c;主要用于客户端与服务器之间的简单请求和响应交互。它的设计理念相对简单&#xff0c;适合处理一些基本的网页服务。 1.2 HTTP1.1 HTTP1.1是HTT…...

30天开发操作系统 第 20 天 -- API

前言 大家早上好&#xff0c;今天我们继续努力哦。 昨天我们已经实现了应用程序的运行, 今天我们来实现由应用程序对操作系统功能的调用(即API, 也叫系统调用)。 为什么这样的功能称为“系统调用”(system call)呢&#xff1f;因为它是由应用程序来调用(操作)系统中的功能来完…...

蓝桥杯(B组)-每日一题(求最大公约数最小公倍数)

题目&#xff1a; 代码展现&#xff1a; #include<iostream> using namespace std; int main() {int m,n,x,y;cin>>m>>n;//输入两个整数int b;bm%n;//取余数xm;//赋值yn;while(b)//当余数不为0的时候{xy;//辗转相除求最小公约数yb;bx%y;}cout<<y<&…...

【DuodooBMS】开源软件:利他也能赚钱,开源MES就是好例子

引一&#xff1a;“开源与商业化”并不矛盾&#xff0c;关键在于为用户提供真正价值&#xff01; 引二&#xff1a;“永远年轻&#xff0c;永远热泪盈眶。” 当你试图放弃一个你知道是正确的事情的时候&#xff0c;希望你能再看看这句话。 在数字时代&#xff0c;开源软件就像…...

LeetCode3. 无重复字符的最长字串(滑动窗口)

题目概述 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的最长子串的长度。 示例 1: 输入: s “abcabcbb” 输出: 3 解释: 因为无重复字符的最长子串是 “abc”&#xff0c;所以其长度为 3。 示例 2: 输入: s “bbbbb” 输出: 1 解释: 因为无重复字符的最长…...

Redis 内存回收机制

Redis 是一个基于内存的键值存储系统&#xff0c;为了避免内存耗尽&#xff0c;Redis 提供了多种内存回收机制。以下是 Redis 内存回收的主要方式&#xff1a; 1. 过期键删除 Redis 支持为键设置过期时间&#xff0c;过期后会自动删除键以释放内存。 1.1 设置过期时间 SET key…...

arduino扩展:Arduino Mega 控制 32 个舵机(参考表情机器人)

参考&#xff1a;表情机器人中使用22个舵机的案例 引言 在电子制作与自动化控制领域&#xff0c;Arduino 凭借其易用性和强大的扩展性备受青睐。Arduino Mega 作为其中功能较为强大的一款开发板&#xff0c;具备丰富的引脚资源&#xff0c;能够实现复杂的控制任务。舵机作为常…...

DeepSeek提问技巧总结

DeepSeek提问技巧总结 1.聚焦核心&#xff0c;细化问题&#xff1a; 提问时应精准明确&#xff0c;避免过于宽泛或模糊。例如不要问“如何学习机器学习&#xff1f;”而应问“零基础如何机器学习”。对于复杂问题&#xff0c;可将其拆解为多个小问题&#xff0c;逐一提问。比…...

基于51单片机的门禁刷卡器proteus仿真

地址&#xff1a;https://pan.baidu.com/s/1j0KAmH5pVGWZWRpT6p5hBg 提取码&#xff1a;1234 仿真图&#xff1a; 芯片/模块的特点&#xff1a; AT89C52/AT89C51简介&#xff1a; AT89C52/AT89C51是一款经典的8位单片机&#xff0c;是意法半导体&#xff08;STMicroelectron…...

mapbox进阶,添加绘图扩展插件,裁剪线

👨‍⚕️ 主页: gis分享者 👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀前言1.1 ☘️mapboxgl.Map 地图对象1.2 ☘️mapboxgl.Map style属性1.3 ☘️MapboxDraw 绘图控件二、🍀添加绘图扩…...

19.4.6 读写数据库中的二进制数据

版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请在显著位置标明本文出处以及作者网名&#xff0c;未经作者允许不得用于商业目的。 需要北风数据库的请留言自己的信箱。 北风数据库中&#xff0c;类别表的图片字段在【数据表视图】中显示为Bitmap Image&#xff1…...