乐观锁及其应用

(笔记总结自《黑马点评》项目)

一、乐观锁

乐观锁:总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不会上锁,只在更新的时候会判断一下在此期间别人有没有去更新这个数据。

二、解决超卖问题

超卖问题:在商品秒杀项目中,线程1过来查询库存,判断出来库存大于1,正准备去扣减库存,但是还没有来得及去扣减,此时线程2过来,线程2也去查询库存,发现这个数量一定也大于1,那么这两个线程都会去扣减库存,最终多个线程相当于一起去扣减库存,此时就会出现库存的超卖问题。

解决方法一:设置版本号。为每一个库存设置版本号,用户每进行一次优惠券获取动作,会先获取库存和版本号,通过后在进行修改数据之前判断先前获取的版本号和数据库中是否一样,如果一样则通过,不一样则说明有其他线程对库存进行过操作,则不通过。

解决方法二:CAS法(Compare and Switch or Set)。利用CAS进行无锁化加锁,实现思路和版本号法一致,只是直接判断库存是否改变,没有设置版本号。

三、代码分析

代码一:

  boolean success = seckillVoucherService.update()
                .setSql("stock= stock -1") //set stick = stock - 1
                .eq("voucher_id", voucherId)
                .eq("stock", voucher.getStock()) // where id = ? and stock = ?
                .update();

这种方法结果测试发现出错率较高。比如同时刻有100个请求,第一个请求成功修改库存,但剩余99个请求在乐观锁判断时都发现数据库的库存数据和原先获取的不一致,导致无法通过,事实上我们在修改数据时只需要判断库存是否大于零即可。

代码二:

  boolean success = seckillVoucherService.update()
                .setSql("stock= stock -1") //set stick = stock - 1
                .eq("voucher_id", voucherId).gt("stock",0)
                .update();

你可能感兴趣的:(java,java,缓存)