当前位置:   article > 正文

Redis实战之-分布式锁-redission_redis分布式锁 redission

redis分布式锁 redission

一、分布式锁-redission功能介绍

基于setnx实现的分布式锁存在下面的问题:

重入问题:重入问题是指 获得锁的线程可以再次进入到相同的锁的代码块中,可重入锁的意义在于防止死锁,比如HashTable这样的代码中,他的方法都是使用synchronized修饰的,假如他在一个方法内,调用另一个方法,那么此时如果是不可重入的,不就死锁了吗?所以可重入锁他的主要意义是防止死锁,我们的synchronized和Lock锁都是可重入的。

不可重试:是指目前的分布式只能尝试一次,我们认为合理的情况是:当线程在获得锁失败后,他应该能再次尝试获得锁。

超时释放:我们在加锁时增加了过期时间,这样的我们可以防止死锁,但是如果卡顿的时间超长,虽然我们采用了lua表达式防止删锁的时候,误删别人的锁,但是毕竟没有锁住,有安全隐患

主从一致性: 如果Redis提供了主从集群,当我们向集群写数据时,主机需要异步的将数据同步给从机,而万一在同步过去之前,主机宕机了,就会出现死锁问题。

那么什么是Redission呢

Redisson是一个在Redis的基础上实现的Java驻内存数据网格(In-Memory Data Grid)。它不仅提供了一系列的分布式的Java常用对象,还提供了许多分布式服务,其中就包含了各种分布式锁的实现。

Redission提供了分布式锁的多种多样的功能

官网地址:Redisson: Easy Redis Java client with features of In-Memory Data Grid

GitHub地址: https://github.com/redisson/redisson

二、分布式锁-Redission快速入门

引入依赖:

  1. <dependency>
  2. <groupId>org.redisson</groupId>
  3. <artifactId>redisson</artifactId>
  4. <version>3.13.6</version>
  5. </dependency>

配置Redisson客户端:

  1. @Configuration
  2. public class RedissonConfig {
  3. @Bean
  4. public RedissonClient redissonClient(){
  5. // 配置
  6. Config config = new Config();
  7. config.useSingleServer().setAddress("redis://192.168.150.101:6379")
  8. .setPassword("123321");
  9. // 创建RedissonClient对象
  10. return Redisson.create(config);
  11. }
  12. }

如何使用Redission的分布式锁

  1. @Resource
  2. private RedissionClient redissonClient;
  3. @Test
  4. void testRedisson() throws Exception{
  5. //获取锁(可重入),指定锁的名称
  6. RLock lock = redissonClient.getLock("anyLock");
  7. //尝试获取锁,参数分别是:获取锁的最大等待时间(期间会重试),锁自动释放时间,时间单位
  8. boolean isLock = lock.tryLock(1,10,TimeUnit.SECONDS);
  9. //判断获取锁成功
  10. if(isLock){
  11. try{
  12. System.out.println("执行业务");
  13. }finally{
  14. //释放锁
  15. lock.unlock();
  16. }
  17. }
  18. }

在 VoucherOrderServiceImpl

注入RedissonClient

  1. @Resource
  2. private RedissonClient redissonClient;
  3. @Override
  4. public Result seckillVoucher(Long voucherId) {
  5. // 1.查询优惠券
  6. SeckillVoucher voucher = seckillVoucherService.getById(voucherId);
  7. // 2.判断秒杀是否开始
  8. if (voucher.getBeginTime().isAfter(LocalDateTime.now())) {
  9. // 尚未开始
  10. return Result.fail("秒杀尚未开始!");
  11. }
  12. // 3.判断秒杀是否已经结束
  13. if (voucher.getEndTime().isBefore(LocalDateTime.now())) {
  14. // 尚未开始
  15. return Result.fail("秒杀已经结束!");
  16. }
  17. // 4.判断库存是否充足
  18. if (voucher.getStock() < 1) {
  19. // 库存不足
  20. return Result.fail("库存不足!");
  21. }
  22. Long userId = UserHolder.getUser().getId();
  23. //创建锁对象 这个代码不用了,因为我们现在要使用分布式锁
  24. //SimpleRedisLock lock = new SimpleRedisLock("order:" + userId, stringRedisTemplate);
  25. RLock lock = redissonClient.getLock("lock:order:" + userId);
  26. //获取锁对象
  27. boolean isLock = lock.tryLock();
  28. //加锁失败
  29. if (!isLock) {
  30. return Result.fail("不允许重复下单");
  31. }
  32. try {
  33. //获取代理对象(事务)
  34. IVoucherOrderService proxy = (IVoucherOrderService) AopContext.currentProxy();
  35. return proxy.createVoucherOrder(voucherId);
  36. } finally {
  37. //释放锁
  38. lock.unlock();
  39. }
  40. }

三、总结

Redisson分布式锁快速入门步骤1:

  1. 引入依赖:在pom.xml中添加Redisson的依赖。
  2. 添加配置:创建一个Config对象,并调用其各种方法来配置Redisson。
  3. 获取Redisson对象:使用Redisson的create方法来获取Redisson对象。
  4. 创建分布式锁:使用Redisson对象调用其lock方法来创建分布式锁。
  5. 解锁:使用Redisson对象调用其unlock方法来解锁。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/码创造者/article/detail/816801
推荐阅读
相关标签
  

闽ICP备14008679号