业务中添加历史版本事务并发处理

news2024/11/25 22:36:58

业务背景:项目中包含历史版本的管理,每次保存历史版本都添加一条新的记录到数据库,且版本号加1。保存版本的时候1.要先查询历史版本数据表,获取当前最新的版本号;2.最新的版本号加1,插入数据历史版本记录表;3.备份一份当前最新的业务内容到业务表。 采用了事务管理@Transactional注解,确保历史版本的正确生成,避免出现版本记录了,但是内容未保存成功的现象。

业务问题:当同一个用户频繁点击多次保存历史版本,出现事务并发,导致出现插入两个相同的历史版本号。这个问题可以由前端控制,不能频繁点击,需等上一次点击返回结果,才可以点击下一次来避免。但是如果这个由后端处理该怎么解决呢?于是开始深入了解一下事务以及MVCC吧。


目录

首先事务四大特性:

事务并发引发的一致性问题:

事务的四种隔离级别:

MVCC多版本并发控制:

首先事务四大特性:

  1. 原子性:是指事务必须是一个原子的操作序列单元;
  2. 一致性:一个事务在执行之前和执行之后,数据库都必须处以一致性状态;
  3. 隔离性:是指在并发环境中,并发的事务是互相隔离的,一个事务的执行不能被其它事务干扰;
  4. 持久性:是指事务一旦提交后,数据库中的数据必须被永久的保存下来。

事务并发引发的一致性问题:

  1. 脏写:如果一个事务修改了另一个未提交事务修改过的数据;
  2. 脏读:一个事务读取了另一个未提交事务修改过的数据;
  3. 不可重复读:一个事务按照某个相同的搜索条件再次读取时得到了和第一次读取时不同的值;
  4. 幻读:一个事务按照某个相同的搜索条件多次读取时,在后续读到了之前没有的记录;

事务的四种隔离级别:

  1. READ UNCOMMITTED:读未提交,可能发生脏读、不可重复读、幻读现象;
  2. READ COMMITTED:读已提交,可能发生不可重复读、幻读现象,解决了脏读的发生;
  3. REPEATABLE READ:可重复读,可能发生幻读现象,但是不可能发生脏读和不可重复读读现象。(默认的,它利用MVCC解决了脏读、不可重复读、幻读等隔离问题,但是不能解决丢失更新问题。)
  4. SERIALIZABLE:可串行化,上述各种现象都不可能发生;

MVCC多版本并发控制:

是一种用来解决读写冲突的无锁并发控制,可以解决并发读写时,互不影响,提高并发读写性能。同时还解决脏读、幻读、不可重复读等事务隔离问题,但不能解决更新丢失问题。

MVCC实现原理是基于聚簇索引中的三个隐藏字段(trx_id,roll_pointer,row_id)、undo日志和readview来实现。

每个事务的id记录在trx_id,roll_pointer指向下一条undo日志,undo日志用来存放改动。rollpointer将改动链成一个版本链。readview用来判断哪个版本对当前事务可见。


以上是对事务的一个总结,那么我实际的业务问题属于什么问题呢?

一个用户同时发起两个版本添加的请求,事务A读取到当前最新版本是2,因为事务A还未提交,所以事务B读取当前最新版本也是2。事务A添加一条最新的记录版本3,事务B也添加一条最新的记录版本3.从而导致最终出现两条版本3的记录,这就相当于事务B的更新结果不正确,应该是版本4或者直接回滚。

出现该问题后,想了很多的解决方案,

方案一:是把隔离级别提高到SERIALIZABLE,让事务串行执行,这样确实只会插入一条记录,第二条的时候会报错出现死锁,从而导致回滚。因为事务A在执行锁定。但是后面查资料一般的话,生产环境不建议使用该方案,并发性差。

 

方案二:查询时添加for update 行级所

Example example = new Example(HistoryPo.class);
example.createCriteria().andEqualTo("Id", Id);
example.setOrderByClause("createTime desc");
example.isForUpdate();
List<HistoryPo> histories = historyPoMapper.selectByExample(example);

该方式无效,因为我的业务不是更新该行数据,而是根据该行数据查询到的版本号,新增一条记录。

还是插入了两条一样的数据

方案三:还考虑了一种方案,查询和插入放在一起

insert into history (ProjectId,Version)
select ProjectId, max(Version)+1 from  history  where ProjectId="xxxxxx" 

 不过这个也只是确保了事务的原子性,还是无法解决并发的问题。

综上,还是由前端控制,同一个人不可同时提交多次版本添加的请求,另一方面提高接口处理的速度。后端处理的话,要么加锁,会导致并发性差。而且最终主要还是业务同时提交也不合理,没有内容变化,提交两个版本意义也不大。

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

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

相关文章

dp算法 力扣174地下城游戏

在学习编程时&#xff0c;算法是一道硬菜&#xff0c;而dp作为算法的一份子&#xff0c;它的地位在编程界举足轻重。 174. 地下城游戏 - 力扣&#xff08;LeetCode&#xff09; 本文是Java代码哦~ 一、题目详情 恶魔们抓住了公主并将她关在了地下城 dungeon 的 右下角 。地…

Vue列表渲染(v-for)以及key的作用与原理

索引值的两种写法&#xff1a; <!--index遍历时的默认索引值--> <ul><li v-for"(p,index) in persons":key"index">{{p.name}}--{{p.age}}</li></ul> 代码&#xff1a; v-for"p in persons" :key"p.id&quo…

【多维数组对象拍平处理为一维数组】

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…

深谋远“绿”,数据中心未来之路在何方?

数据中心未来演进方向是什么&#xff1f; 在中国绿色算力大会-华为数据中心平行会议上&#xff0c;业界愈发形成共识&#xff1a;即在双碳目标的大背景下&#xff0c;数据中心走向绿色低碳化、智能化。 去年初&#xff0c;东数西算工程正式启动建设&#xff0c;标志着我国数据…

Ui自动化测试上传文件方法都在这里了

目录 前言 被测HTML代码 send_keys方法 实例------------------------------------ Time : 2019/7/17 19:03 Auth : linux超 File : upload_file_send_keys.py IDE : PyCharm Motto: Real warriors,dare to face the bleak warning,dare to face the incisive error! QQ : 2…

代码随想录第26天 | ● 332.重新安排行程 ● 51. N皇后 ● 37. 解数独

332. 重新安排行程 /*** param {string[][]} tickets* return {string[]}*/var findItinerary function (tickets) {let s "ZZZ";let start;for (let i in tickets) {if (tickets[i][0] "JFK" && tickets[i][1] < s) {start i;s tickets[i…

密码学学习笔记(十三):哈希函数 - Merkle–Damgård结构

Merkle–Damgrd是一种算法&#xff0c;由Ralph Merkle和Ivan Damgrd提出。它通过迭代调用压缩函数来计算消息的哈希值。 应用 拿SHA-2举例&#xff0c;首先我们需要对需要进行哈希运算的输入做填充&#xff0c;然后将填充后的输入划分为等长的分组&#xff0c;每个分组的长度…

uniapp 土法 瀑布流 - vue3

效果图 代码 <template><view><!-- 瀑布流展示 --><!-- 标签页 --><view class="rowStart flexNoLineBreaking paddingCol10 innerDomPaddingRow5 tinyShadow marginBottom10"><view @click="tabsCurrent = 0; run_waterfa…

计算机网络基础第六章

一、应用层概述 1.1 网络应用模型 1.1.1 客户/服务器(C/S)模型 1.1.2 P2P模型 二、域名解析系统——DNS系统 2.1 域名 2.2 域名服务器 2.3 域名解析过程 三、文件传输协议——FTP 3.1 FTP服务器和用户端 3.2 FTP工作原理 四、电子邮件 4.1 电子邮件系统概述 4.2 简单邮件传送…

C# Modbus通信从入门到精通(1)——Modbus RTU(虚拟串口调试工具的使用)

前言: 订阅本专栏后,加入vip专属的qq群,在群资料里面就能找到虚拟串口工具 1、安装虚拟串口工具 第1步、双击vspd.exe安装 第2步、 打开“Cracked”的文件夹,里面有一个vspdct.dll,如下图:把这个dll粘贴到C:\Program Files (x86)\Eltima Software\Virtual Serial Po…

Python垃圾回收

Python垃圾回收 文章目录 Python垃圾回收引用计数标记清除分代回收 GC作为现代编程语言的自动内存管理机制&#xff0c;专注于两件事&#xff1a; 找到内存中无用的垃圾资源清除这些垃圾并把内存让出来给其他对象使用。 GC彻底把程序员从资源管理的重担中解放出来&#xff0c;让…

MySQL-DML-添加数据insert

目录 添加数据&#xff1a;insert insert语法 注意事项 修改数据&#xff1a;update update语法 注意事项&#xff1a; 删除数据&#xff1a;delete 删除语法 注意事项 总结 DML英文全称Data Manipulation Language&#xff08;数据操作语言&#xff09;&#xff0c;…

数据结构---B+Tree

文章目录 BTree简单了解一下BTree MySQL表数据文件MyISAM存储引擎和InnoDB存储引擎的区别&#xff1f; BTree 在我没了解BTree之前&#xff0c;听别人提到这个词时&#xff0c;脑子一片空白&#xff0c;懵懵的&#xff0c;今天利用空闲时间&#xff0c;简单了解了一下BTree&am…

去掉浮夸,空杯心态重新面对测试

刚开始一头扎进软件测试行业&#xff0c;从踏踏实实的机械化功能测试&#xff0c;到学会和甲方扯皮&#xff0c;到被鄙视的五体投地后抓紧修炼表面功夫来忽悠人&#xff0c;学的最多的反而是怎么与人交流。第一次面对跳槽的机会&#xff0c;我竟然发现自己的测试能力不升反降。…

微服务系统面经

微服务架构 秒杀微服务架构图 项目地址可以参考&#xff1a;秒杀系统 1 一个java的微服务系统中有几个网关&#xff1f; 在一个Java的微服务系统中&#xff0c;网关的数量并不固定&#xff0c;这完全取决于系统的设计和需求。网关服务是微服务架构中的重要组件&#xff0c;它…

架构训练营学习笔记:4-4如何设计存储架构?

存储架构设计的三个步骤 分为&#xff1a;1 估算性能需求 2、选择存储系统 3 设计存储方案 性能估算步骤 一 用户量预估 2B的业务&#xff0c;数据量需要预估&#xff0c;2C的需要决策。 方法&#xff1a; 规划&#xff1a;根据成本、预算、目标等确定 推算&#xff1a;基于…

SRA数据下载的一个坑

前两天协助处理GEO数据上的一个单细胞数据&#xff0c;发现了一个巨坑&#xff0c;这里分享下&#xff0c;希望大家能避开。 需要下载的数据集是&#xff0c;GSE119562&#xff0c;查询SRA Run Selector&#xff0c;找到它对应的SRR编号。 于是&#xff0c;我非常熟练的用pref…

【接口自动化测试】HTTP协议详解

协议 简单理解&#xff0c;计算机与计算机之间的通讯语言就叫做协议&#xff0c;不同的计算机之间只有使用相同的协议才能通信。所以网络协议就是为计算机网络中进行数据交换而建立的规则&#xff0c;标准或约定的集合。 OSI模型 1978年国际化标准组织提出了“开放系统互联网…

java实现敏感词过滤,简单实例,dfa算法

java实现敏感词过滤&#xff0c;简单实例&#xff0c;dfa算法 最近在看黑马的视频学习的时候&#xff0c;看到了&#xff0c;自定义敏感词过滤的&#xff0c;感觉蛮有意思的&#xff0c;记录一下。 直接上实例 第一步初始化敏感词&#xff08;可以写死&#xff0c;当然在开发…

Ceres Solver简介及使用

Ceres Solver是一个开源的C库&#xff0c;用于建模和解决大型、复杂的优化问题。它是一个成熟、功能丰富且高性能的库&#xff0c;自2010年以来一直在Google生产中使用。最新发布版本为2.1.0,license为BSD,它支持在Windows、Linux、Mac、Android、iOS上编译&#xff0c;源码地址…