【并发控制、更新、版本控制】.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,一经查实,立即删除!

相关文章

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

在数据管理的庞大体系中&#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 数据类型的特点 键值对集合…

支持向量机原理

支持向量机&#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…

C++引用深度详解

C引用深度详解 前言1. 引用的本质与核心特性1.1 引用概念1.2 核心特性 2. 常引用与权限控制2.1 权限传递规则2.2 常量引用2.3 临时变量保护1. 样例2. 样例3. 测试 三、引用使用场景分析3.1 函数参数传递输出型参数避免多级指针高效传参 3.2 做函数返回值正确使用危险案例 4. 性…

本地部署Deepseek R1

使用Ollama open-webui部署Deepseek R1 一、安装Ollama 官网地址&#xff1a;https://ollama.com/&#xff0c;点击下载按钮选择windows版本。并安装 打开命令提示符输入ollama&#xff0c;出现一下提示命令表示ollama安装完成 二、使用Ollama下载deepseek R1不同模型 打开o…

MATLAB 生成脉冲序列 pulstran函数使用详解

MATLAB 生成脉冲序列 pulstran函数使用详解 目录 前言 一、参数说明 二、示例一 三、示例二 总结 前言 MATLAB中的pulstran函数用于生成脉冲序列&#xff0c;支持连续或离散脉冲。该函数通过将原型脉冲延迟并相加&#xff0c;生成脉冲序列&#xff0c;适用于信号处理和系统…

机器学习(李宏毅)——self-Attention

一、前言 本文章作为学习2023年《李宏毅机器学习课程》的笔记&#xff0c;感谢台湾大学李宏毅教授的课程&#xff0c;respect&#xff01;&#xff01;&#xff01; 二、大纲 何为self-Attention&#xff1f;原理剖析self-Attention VS CNN、RNN、GNN 三、何为self-Attenti…

RagFlow + Docker Desktop + Ollama + DeepSeek-R1本地部署自己的本地AI大模型工具

前期准备 首先&#xff0c;我们需要下载 Ollama 以及配置相关环境。 Ollama 的 GitHub仓库 &#xff08;https://github.com/ollama/ollama&#xff09;中提供了详细的说明&#xff0c;简单总结如下: Step1&#xff1a;下载 Ollama 下载&#xff08;https://ollama.com/dow…

【数据结构】双向链表(真正的零基础)

链表是一种物理存储单元上非连续、非顺序的存储结构。数据元素的逻辑顺序是通过指针的链接来实现的&#xff01;在上篇我们学习了单向链表&#xff0c;而单向链表虽然空间利用率高&#xff0c;插入和删除也只需改变指针就可以达到&#xff01;但是我们在每次查找、删除、访问..…

网络编程-day5-sqlite3数据库

思维导图 服务器 #include <stdio.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <pthread.h> #include <semaphore.h>…

Spring AI 介绍

文章来源&#xff1a;AI 概念 (AI Concepts) _ Spring AI1.0.0-SNAPSHOT中文文档(官方文档中文翻译)|Spring 教程 —— CADN开发者文档中心 本节介绍 Spring AI 使用的核心概念。我们建议仔细阅读它&#xff0c;以了解 Spring AI 是如何实现的。 模型 AI 模型是旨在处理和生成…

【Elasticsearch】监控与管理:集群监控指标

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;精通Java编…

黑马Redis详细笔记(实战篇---短信登录)

目录 一.短信登录 1.1 导入项目 1.2 Session 实现短信登录 1.3 集群的 Session 共享问题 1.4 基于 Redis 实现共享 Session 登录 一.短信登录 1.1 导入项目 数据库准备 -- 创建用户表 CREATE TABLE user (id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT 用户ID,phone …

大前端之前端开发接口测试工具postman的使用方法-简单get接口请求测试的使用方法-简单教学一看就会-以实际例子来说明-优雅草卓伊凡

大前端之前端开发接口测试工具postman的使用方法-简单get接口请求测试的使用方法-简单教学一看就会-以实际例子来说明-优雅草卓伊凡 背景 前端开发接口请求&#xff0c;调试&#xff0c;联调&#xff0c;接入数据&#xff0c;前端必不可少工具&#xff0c;postman是一个非常好…