标签:相同 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不能相同。保证唯一性。
标签:相同 detail 唯一性 最大 png conf ima mamicode alt
原文地址:https://www.cnblogs.com/tommaoxiaoqi/p/12628842.html