redisson3.15.0的引入原因及使用

引入redisson的背景

  • 由于redis与mysql会出现数据不一致的情况,在更新mysql数据与更新redis数据存在时间差,不同线程的时间差可能不同,例子:A线程更新mysql数据为2,此时A线程卡顿,然后B线程更新mysql数据为3,B线程更新redis数据为3,之后A线程恢复执行,A线程更新redis数据为2;此时出现数据不一致问题,即使:mysql数据为3,redis数据为2
  • 针对redis与mysql数据不一致问题;根据需求及并发量,有不同的解决方案。比如:设置数据的过期时间,延迟双删,写多读多直接不使用redis
  • 延迟双删,对于需要延迟的时间,需要设置的比业务代码执行的时间长,但是业务代码执行的时间是不定的,延迟时间设置的过长过短均会出现问题。因此可以采用分布式锁redisson
  • 在不考虑主从高可用的情况下,可用采用redisson分布式锁,将并行的代码,变成串行,即可解决数据不一致问题。例子:A线程更新mysql数据,更新redis数据执行完毕后,B线程再执行;此时不会出现数据不一致问题
  • redisson除解决数据不一致问题,还可以做为分布式锁;如果读多写少,可以使用redisson的读写锁优化性能

项目中引入redisson

  • 项目已经引入redis
  • pom中引入redisson3.15.0依赖
<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson</artifactId>
    <version>3.15.0</version>
</dependency>
  • 测试使用代码
        // 开始加锁,锁名称不与他人重复
        Lock lock = redissonClient.getLock("lock");
        lock.lock();
        try {
            // 执行业务代码
            Thread.sleep(1000);
        } catch (Exception e) {
            log.info("异常, {}", e.getMessage());
            throw new RuntimeException(e);
        } finally {
            lock.unlock();
        }

redisson相关问题

  • 底层通过lua脚本实现
 -- 若锁不存在:则新增锁,并设置锁重入计数为1、设置锁过期时间
if (redis.call('exists', KEYS[1]) == 0) then
    redis.call('hset', KEYS[1], ARGV[2], 1);
    redis.call('pexpire', KEYS[1], ARGV[1]);
    return nil;
end;
 
-- 若锁存在,且唯一标识也匹配:则表明当前加锁请求为锁重入请求,故锁重入计数+1,并再次设置锁过期时间
if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then
    redis.call('hincrby', KEYS[1], ARGV[2], 1);
    redis.call('pexpire', KEYS[1], ARGV[1]);
    return nil;
end;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值