【并发控制、更新、版本控制】.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 系列


在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/70836.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

结合实际讲NR系列2—— SIB1

这是在基站抓取的sib1的一条信令 L3MessageContent BCCH-DL-SCH-Messagemessagec1systemInformationBlockType1cellSelectionInfoq-RxLevMin: -64q-QualMin: -19cellAccessRelatedInfoplmn-IdentityListPLMN-IdentityInfoplmn-IdentityListPLMN-IdentitymccMCC-MNC-Digit: 4MC…

数据存储和操作:数据管理的基石

在数据管理的庞大体系中&#xff0c;数据存储和操作是确保数据可用性和完整性的关键环节。它不仅涉及数据的物理存储&#xff0c;还包括数据的管理、维护和优化。今天&#xff0c;让我们深入《DAMA数据管理知识体系指南&#xff08;第二版&#xff09;》的第六章&#xff0c;一…

Redis 数据类型 Hash 哈希

在 Redis 中&#xff0c;哈希类型是指值本⾝⼜是⼀个键值对结构&#xff0c;形如 key "key"&#xff0c;value { { field1, value1 }, ..., {fieldN, valueN } }&#xff0c;Redis String 和 Hash 类型⼆者的关系可以⽤下图来表⽰。 Hash 数据类型的特点 键值对集合…

LLaMA-Factory 安装linux部署conda笔记

第一行代码是我导入https://github.com/hiyouga/LLaMA-Factory.git到我的项目那里的&#xff0c;试过网上随便搜索过相同&#xff0c;估计没更新&#xff0c;安装了几次都运行失败&#xff0c;克隆了最新的就安装成功了。 方法1没虚拟环境&#xff1a;不知道成不成功&#xff…

【干活分享】2025年可以免费问答的一些GPT网站-deepseek等免费gpt

2025年已经到来&#xff0c;大家也都陆续回归到忙碌的工作中。在新的一年里&#xff0c;如何更高效地完成工作任务&#xff0c;提升工作效率&#xff0c;是很多人关心的问题。今天&#xff0c;就为大家分享一些实用性很强的GPT网站&#xff0c;帮助大家在工作中事半功倍。 Dee…

Repo命令使用

repo 命令与 git 类似&#xff0c;但它主要用于管理多个 Git 仓库的操作。以下是等效的 repo 命令&#xff1a; 1. 获取新仓库代码 克隆仓库 repo init -u <manifest_url> -b <branch_name> repo sync repo init&#xff1a;初始化 repo&#xff0c;指定远程清单…

【生产变更】- Oracle RAC添加配置ipv6地址

【生产变更】- Oracle RAC添加配置ipv6地址 一、概述二、环境检查及备份2.1 检查并备份系统层面IP配置2.2 检查并备份监听配置2.3 检查并备份网卡配置2.4 检查并备份/etc/hosts三、集群层面配置3.1 检查集群配置3.2 停止集群组件3.3 Bond0网卡设置3.4 /etc/hosts文件配置3.5 重…

docker部署superset并连接华为MRS hive数据库

下载构建源码 这个项目实现了汉化和开箱即用&#xff0c;感谢大佬 GitHub - lutinglt/superset-zh: Superset 汉化, Superset 中文版 替换国内apt源 查看debian版本&#xff0c;不同版本替换apt源的内容不同 cat /etc/debian_version我这里是11.9版本 apt源文件sources.li…

qt 事件的传递顺序

在 Qt 中&#xff0c;事件的传递顺序遵循以下基本规则&#xff1a; 事件的产生&#xff1a;当用户与界面交互时&#xff0c;操作&#xff08;如鼠标点击、键盘输入等&#xff09;会生成相应的事件&#xff08;如 QMouseEvent、QKeyEvent 等&#xff09;。 事件的传递顺序&…

AJAX XML技术详解

AJAX XML技术详解 引言 随着互联网技术的不断发展,前端与后端之间的交互需求日益增长。AJAX(Asynchronous JavaScript and XML)技术应运而生,成为实现前后端分离、提高页面响应速度的关键技术之一。本文将详细介绍AJAX XML技术,包括其原理、应用场景、优缺点等内容。 A…

mybatis 是否支持延迟加载?延迟加载的原理是什么?

1. MyBatis 是否支持延迟加载&#xff1f; 是的&#xff0c;MyBatis 支持延迟加载。延迟加载的主要功能是推迟数据加载的时机&#xff0c;直到真正需要时再去加载。这种方式能提高性能&#xff0c;尤其是在处理关系型数据时&#xff0c;可以避免不必要的数据库查询。 具体来说…

全面理解-c++中的异常处理机制

C 的异常处理机制是一种用于处理程序运行时错误的结构化方法&#xff0c;通过分离正常逻辑与错误处理代码&#xff0c;提高代码的可读性和可维护性。以下是其核心组成部分和工作原理的详细说明&#xff1a; 1. 异常处理的三大关键字 1.1 try 块 作用&#xff1a;包裹可能抛出异…

支持向量机原理

支持向量机&#xff08;简称SVM&#xff09;虽然诞生只有短短的二十多年&#xff0c;但是自一诞生便由于它良好的分类性能席卷了机器学习领域。如果不考虑集成学习的算法&#xff0c;不考虑特定的训练数据集&#xff0c;尤其在分类任务中表现突出。在分类算法中的表现SVM说是排…

zy.21

PHP(续) PHP代码执行漏洞 1.PHP中代码漏洞的概念 代码执行漏洞就是在代码中若存在eval、assert等能将所接收的参数作为代码去执行,并且拼接的内容可被访问者控制,也就是把传入的参数给拼接进去了,造成了额外的代码执行,也就造成了代码执行漏洞。&#xff08;大概原理&#x…

LSTM 学习笔记 之pytorch调包每个参数的解释

0、 LSTM 原理 整理优秀的文章 LSTM入门例子&#xff1a;根据前9年的数据预测后3年的客流&#xff08;PyTorch实现&#xff09; [干货]深入浅出LSTM及其Python代码实现 整理视频 李毅宏手撕LSTM [双语字幕]吴恩达深度学习deeplearning.ai 1 Pytorch 代码 这里直接调用了nn.l…

React - 事件绑定this

在 React 中&#xff0c;this 的绑定是一个常见问题&#xff0c;尤其在类组件中使用事件处理函数时。JavaScript 中的 bind 函数用于设置函数调用时 this 的值。 bind 函数的作用 bind() 方法创建一个新的函数&#xff0c;当被调用时&#xff0c;其 this 关键字被设置为提供的…

Web3 的虚实融合之路:从虚拟交互到元宇宙构建

在这个数字技术日新月异的时代&#xff0c;我们正站在 Web3 的门槛上&#xff0c;见证着互联网的又一次革命。Web3 不仅仅是技术的迭代&#xff0c;它代表了一种全新的交互方式和价值创造模式。本文将探讨 Web3 如何推动虚拟交互的发展&#xff0c;并最终实现元宇宙的构建&…

Kafka简单使用

说明&#xff1a;kafka是一款消息中间件&#xff0c;可实现微服务之间的异步调用。本文介绍kafka的简单使用。windows操作系统下的kafka安装&#xff0c;参考下面这篇文章 Kafka安装 启动 按照上面博客的介绍&#xff0c;使用CMD命令启动&#xff0c;如下&#xff1a; Demo …

【原创精品】基于Springboot3+Vue3的学习计划管理系统

大家好&#xff0c;我是武哥&#xff0c;最近给大家手撸了一个基于SpringBoot3Vue3的学习计划管理系统&#xff0c;可用于毕业设计、课程设计、练手学习&#xff0c;系统全部原创&#xff0c;如有遇到网上抄袭站长的&#xff0c;欢迎联系博主~ 项目演示视频 https://www.bili…

为什么我用Python控制仪器比C#慢很多?如何优化性能?

在自动化测试、实验室仪器控制等领域&#xff0c;Python、C# 和 C 是常见的编程语言选择。最近&#xff0c;我在使用 Python 控制仪器时&#xff0c;发现其交互速度明显比 C# 慢很多。这让我感到困惑&#xff0c;毕竟 Python 以其简洁和高效著称&#xff0c;为什么会出现这种情…