码迷,mamicode.com
首页 > 数据库 > 详细

数据库表中非主键字段自动加1功能

时间:2020-04-03 21:34:27      阅读:87      评论:0      收藏:0      [点我收藏+]

标签:相同   detail   唯一性   最大   png   conf   ima   mamicode   alt   

数据库版本表t_version包含的字段:

技术图片

 

用户创建config,在一个config下创建多个版本。 

在创建版本时,versionId字段要在该config下上一个版本ID的基础上自动加1.

 

在创建版本时,使用@Transaction注解设置数据库事务。

技术图片

 

 获取当前config的最大版本号

技术图片

 

 

此时存在的问题:用户A在获取到当前最大版本后,用户B同时也获取了当前最大版本 值与A相同,A创建版本,B再创建版本。就会存在两个相同的versionId。

 

思路1:

了解了数据库的隔离级别:

1.Read Uncommitted:可以读到未提交的数据。脏读:读到了其他人未提交的数据。

2.Read Committed:只能读到已提交的数据。第一次读5,其他人改成了4,再读是4。不可重复读:同一个字段两次不同值。

3.Repeated Read:第一次读5,其他人改成了4,再读还是5。mysql默认级别。   幻读:读到了新增条目。

4.Serializable:串行。事务一个个排队执行。

 

尝试将隔离级别设为最严格的串行: 

@Transactional(isolation = Isolation.SERIALIZABLE)

 

此时问题:出现死锁。

原因:

用户A获得了configId = 1的读锁A。
而在同时,B获得configId = 1的读锁B。
创建时,A尝试获得configId = 1的写锁,这个时候,由于configId = 1处不仅有事务A的读锁,还有事务B的读锁,因此事务A的update操作获取锁被阻塞。
此时,当事务B继续执行update操作时,由于事务A又拥有configId = 1的读锁A,因此进入互相等待状态,造成死锁。

参考:https://blog.csdn.net/weixin_38553453/article/details/83037979

项目中不能用事务的串行级别。

 

思路2:读取数据库值的时候采用 select for update 来读。

 

思路3:使用联合索引。采用该方式。

技术图片

 

 同一个configId它的VersionId不能相同。保证唯一性。

 

数据库表中非主键字段自动加1功能

标签:相同   detail   唯一性   最大   png   conf   ima   mamicode   alt   

原文地址:https://www.cnblogs.com/tommaoxiaoqi/p/12628842.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!