在今天做的项目练习部分中真的学到了很多东西,也补充了许多之前遗漏或是忘记的知识点,但时间精力有限,我就先记录一下今天用到的一个新东西,悲观锁和乐观锁。
首先给出实际应用背景:
在加入锁和事务注解之前,这里有着很明显的并发问题,如果没有红圈中的部分,会出现以下情况
没有锁导致:
①多个用户快速点击,仅剩1张优惠券,却多个用户都抢到了优惠券(即user_coupon中新增了多条记录)!!!
没有事务导致:
①假设在if(i==0)代码块中抛出了异常,但由于没有加入事务注解,因此无法回退,导致了“更新coupon表中的相关数据”这一步造成的影响无法恢复!!!
而加入了悲观锁和事务注解以后就很好的解决了这些并发问题!
=========================================================================
其次这里的使用还有许多细节,eg:
①锁对象用到的是user.toString().intern() 而不是 user.toString()
(这一点牵扯到了spring的动态代理,我会在明天的博客中解释并把链接粘过来)
②锁和事务的顺序:上锁——>事务开启——>事务上交——>开锁
(这一点属于事务边界和锁边界问题,同样的,明天补充)
接下来是我用到的一个乐观锁(严格来讲它属于数据库层面的乐观锁机制):
从图中的红圈部分可以看出,它为了避免这一种高并发情况:
①假设有2个用户都通过了之前的层层校验来到了这里,但实际上这里只能再新增1条数据,如果没有红圈中的条件,就会导致增加了2条数据(即issue_num>=total_num),而这并不符合业务逻辑
有了红圈中的类似于乐观锁思想的条件,再进行一次对数据的判断,可以有效解决并发问题!