基于Redisson实现分布式锁

自古美人都是妖i 提交于 2020-04-20 12:48:00

超卖现象一 :解决方式

1.扣除库存不在程序中进行,而在数据库中

2.向数据库传递库存增量,扣减1个库存,增量为-1

3.在数据库update语句计算库存,通过update行锁解决并发

 

超卖现象二:解决方案

1.校验库存,扣除库存统一加锁

2.使之成为原子操作

3.并发时,只有获得锁的线程才能校验,扣除库存

4.扣除库存结束后,释放锁

5.确保库存不会扣成负数

 

 

使用redisson 实现分布式锁------------------------------------------------------start-------------------------------------------------------------------------

        <dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson-spring-boot-starter</artifactId>
            <version>3.12.0</version>
        </dependency>

 

@Autowired
private RedissonClient redissonClient;

 

 

/**
         *  分布式锁【3】 编写业务代码
         *  1、Redisson是基于Redis,使用Redisson之前,项目必须使用Redis
         *   2、注意getLock方法中的参数,以specId作为参数,每个specId一个key,和
         *   数据库中的行锁是一致的,不会是方法级别的锁
        |

@Override
@Transactional(propagation = Propagation.REQUIRED)
public void decreaseItemSpecStock(String itemSpecId, Integer buyCounts) {

    /**
     * 1.查询库存为
     * 2.判断库存是否减少到0以下
     */
    //锁
    RLock lock = redissonClient.getLock("item_lock" + itemSpecId);
    //5s 发生异常会在5s释放锁
    /**
     * 1、获取分布式锁,锁的超时时间是5秒get
    *  2、获取到了锁,进行后续的业务操作
    */
    lock.lock(5, TimeUnit.SECONDS);
    try {
        int result = itemsMapperCustom.decreaseItemSpecStock(itemSpecId, buyCounts);
        if (result != 1) {
            throw new RuntimeException("订单创建失败,原因:库存不足!");
        }
    } catch (RuntimeException e) {
        throw e;
    } finally {
        //解锁  /**
    *  不管业务是否操作正确,随后都要释放掉分布式锁
    *   如果不释放,过了超时时间也会自动释放
    */        lock.unlock();
    }

使用redisson 实现分布式锁------------------------------------------------------end-------------------------------------------------------------------------

 

 

 

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!