实现低并发简单的一个乐观锁

一次低并发然而需要用到锁的需求解决

*需求

    学生预约实验室,因为实验室有最大预约人数,当并发请求过多,可能会造成多人成功预约同一个‘最后的位置’

*具体表情况
一个学生预约情况表(Condition表),记录实验室预约情况,有人数字段(每次有新预约,要更新这个数字,然后往学生预约表(Appointment表)插入一条新纪录),实验室ID字段等

*解决思路
1、涉及多表插入修改,添加事务管理,这里要实现成功预约的条件Condition表人数字段加一,然后预约表插入新纪录
2、那么service方法内代码查、填充对象字段逻辑不变,更新时加where条件,要更新Appointment行记录ID字段以及此行对应的人数,这两个字段唯一标志一次历史记录,所以修改时添加这两个字段判断相等的条件,
3、如果修改影响行数大于一,说明前面读到的这条记录在表中未发生变化,这期间无人新预约,若修改影响行数<1,则表示这行记录对应的人数字段已经修改,此次预约失败

*解决要点:(自定义乐观锁逻辑)

1、预约失败手动抛出异常,事务回滚,或者手动回滚,使用spring框架可以将@Transactional的rollbackFor属性设置为Exception.class
2、修改时依据为ConditionID和对应此行人数两个字段
3、提供预约失败自动重新预约机制
体现:预约失败假如是因为并发操作的问题,造成修改时数据不一致,那么根据ConditionId再次向数据库请求这条数据,读取人数,然后按照上面的逻辑,再次对Condition表这条记录进行修改,依据仍然为ConditionID和这条记录对应的人数(防止多次并发)
要实现三的一个重点是将此方法数据库隔离级别设置为read_uncomminted(因为需求需要要对同一个表对此查询,并且想要得到最新字段值),事务传播行为我设置为REQUIRED,经测试REQUIRES_NEW也是可以的,如果你不是使用的spring框架,事务传播行为可以不用关心


总结不易,望转发时带上原文链接,感谢!

猜你喜欢

转载自blog.csdn.net/baidu_38609744/article/details/81564460