7-1 介绍一下你们项目中的优惠券功能
在我的项目中,优惠劵是有发放和领取两种规则
优惠卷的发放分为:立即发放,定时发放
- 立即发放:优惠券立刻生效,直接出现在用户端页面供用户领取
- 定时发放:定一个发放开始时间,时间到期后才会进入出现在用户端页面
同时优惠券的领取方式也分两种,手动领取和指定发放
- 手动领取:就是展示在用户端页面,由用户自己手动点击领取
- 指定发放:就是兑换码模式,后台给优惠券生成N张兑换码,由管理员发放给指定用户。
7-2 你们项目中是如何防止优惠券超领的
在项目中优惠卷超领分为两种情况,分别为多人超卖问题,和单人超卖问题
发生多人超卖的原因是在多线程的情况下,我们的逻辑步骤是独立的,不具备原子性,当线程1尚未更新时线程2就来查询,此时查到的库存数据是旧的,但是线程2又不知道就会认为库存充足,就会导致并发安全问题产生,
解决方案就是加锁,锁一般分为:悲观锁,和乐观锁,
在更新数据前先判断数据与我之前查询到的是否一致,不一致则证明有其它线程也在更新。为了避免出现安全问题,放弃本次更新或者重新尝试一次。此方案:性能好、安全性也好,但是并发较高时,可能出现更新成功率较低的问题因此我们可以使用乐观锁解决上面代码的问题
单人超卖是因为多个用户并发场景下,实时查询的判断逻辑会存在失效问题,
对于读的操作我们一般使用的是悲观锁,这里我们可以Synchronized实现,把用户的id做为锁对象,但要在用户id后面.toString().intern()来解决最终的问题。只要两个字符串equals的结果为true,那么intern就能保证得到的结果用 ==判断也是true
以上就是两种问题的解决方式。
7-3 事务失效的场景有哪些
事务失效的场景主要有五种:
- 事务方法非public修饰
- 非事务方法调用事务方法
- 事务方法的异常被捕获
- 事务异常类型不对
- 事务传播行为不对