springboot集成分布式锁redissonLock

引入依赖

  <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>fastjson</artifactId>
      <version>1.2.68</version>
  </dependency>
  <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>log4j-over-slf4j</artifactId>
  </dependency>
  <dependency>
      <groupId>org.redisson</groupId>
      <artifactId>redisson</artifactId>
      <version>3.14.0</version>
  </dependency>

RedissonConfig

创建连接

@Configuration
public class RedissionConfig {
    @Bean
    public RedissonClient getRedisson() {
        Config config = new Config();
        config.useSingleServer().setAddress("redis://127.0.0.1:6379");
        return Redisson.create(config);
    }
}

RedissonUtil

@Component
public class RedissonUtil {

	@Autowired
	private RedissonClient redissonClient;

	private Logger logger = Logger.getLogger(RedissonUtil.class);

	private final String LOCK_FLAG = "rlock_";

    /**
     * 根据name对进行上锁操作,redissonLock 阻塞事的,采用的机制发布/订阅
     * @param lockName
     */
    public void lock(String lockName, int timeOutMinute) {
        String key = LOCK_FLAG + lockName;
        RLock lock = redissonClient.getLock(key);
        //lock提供带timeout参数,timeout结束强制解锁,防止死锁 :1分钟
        lock.lock(timeOutMinute, TimeUnit.MINUTES);
    }
    
    /**
     * 根据name对进行上锁操作,redissonLock 阻塞事的,采用的机制发布/订阅
     * @param lockName
     */
    public void lock(String lockName) {
        String key = LOCK_FLAG + lockName;
        RLock lock = redissonClient.getLock(key);
        lock.lock();
    }

	/**
	 * 根据name进行上锁操作,redissonLock 非阻塞的
	 *
	 * @param lockName
	 * @param waitTime 毫秒,等待锁的时间,等待超时即放弃
	 * @return true锁成功,false锁失败
	 */
	public boolean trylock(String lockName, long waitTime) {
		try {
			String key = LOCK_FLAG + lockName;
			RLock lock = redissonClient.getLock(key);
			return lock.tryLock(waitTime, TimeUnit.MILLISECONDS);
		} catch (Exception e) {
			return false;
		}
	}

	/**
	 * 多重锁
* 根据name进行上锁操作,redissonLock 非阻塞的 * * @param lockNamePre 锁前缀 * @param waitTime 毫秒,等待锁的时间,等待超时即放弃 * @param args 锁后缀列表 * @return true锁成功,false锁失败 */
public boolean trylock(String lockNamePre, List<String> args, long waitTime) { boolean flag; RLock[] locks = new RLock[args.size()]; for (int i=0;i<args.size();i++) { String key = LOCK_FLAG + lockNamePre + args.get(i); RLock lock = redissonClient.getLock(key); locks[i] = lock; } RLock multiLock = redissonClient.getMultiLock(locks); try { flag = multiLock.tryLock(waitTime, TimeUnit.MILLISECONDS); } catch (Exception e) { flag = false; } return flag; } /** * 根据name进行解锁操作 * * @param lockNamePre 锁前缀 * @param args 锁后缀列表 */ public void unlock(String lockNamePre, List<String> args) { RLock[] locks = new RLock[args.size()]; for (int i=0;i<args.size();i++) { String key = LOCK_FLAG + lockNamePre + args.get(i); RLock lock = redissonClient.getLock(key); locks[i] = lock; } RLock multiLock = redissonClient.getMultiLock(locks); multiLock.unlock(); } /** * 根据name对进行解锁操作 * @param lockName */ public void unlock(String lockName) { String key = LOCK_FLAG + lockName; RLock lock = redissonClient.getLock(key); lock.unlock(); } }

使用分布式锁

@Service
public class StockFlowServiceImpl extends ServiceImpl<StockFlowMapper, SkillStockFlow> implements StockFlowService {
    @Autowired
    private ActivityItemServiceImpl activityItemService;
    @Autowired
    private RedissonUtil redissonUtil;
    @Override
    public boolean skillItem(SkillDto skillDto) {
        boolean trylock = false;
        String orderId = UUID.randomUUID().toString().replace("-","");
        //lockName不一样,持的锁就不一样
        String lockName = skillDto.getItemId();

        try {
            trylock = redissonUtil.trylock(lockName,100);
            if (!trylock){
                return false;
            }
            boolean flag = activityItemService.reduceStock(skillDto.getItemId(), skillDto.getBuyNum());
            if (flag){
                SkillStockFlow skillStockFlow = new SkillStockFlow();
                BeanUtils.copyProperties(skillDto,skillStockFlow);
                skillStockFlow.setOrderId(orderId);
                save(skillStockFlow);
            }
            return true;
        } catch (BeansException e) {
            e.printStackTrace();
            return false;
        } finally {
            if (trylock){
                redissonUtil.unlock(lockName);
            }
        }
    }
}

参考博客:
Redisson重连后WatchDog失效问题解决http://events.jianshu.io/p/84522c2736a2

获取锁的原理参考博客:https://blog.csdn.net/qq_41489540/article/details/113772408

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