扫码关注官方订阅号
ringa_lee
自己琢磨的一个方法,让key和exists过期时间保持一致就行,不知道还有没有更好的方法
String key = "key"; String exists = key + ":exists"; if (redisConnection.setNX(exists, "1") == 1) { redisConnection.setNX(key, value); return value; } else { return redisConnection.incr(key); }
jedis.set(key, value, nxxx, expx, time)
如果想把逻辑弄成redis的一个事务做完,弄个lua来做
我的理解是,应该没有完美的方案
如果用@twayne 的方案,在并发的情况下回出现另外一个线程执行到redisConnection.incr(key),但是redisConnection.setNX(key, value)这步并没有完成
redisConnection.incr(key)
redisConnection.setNX(key, value)
用@yuwenbao的lua脚本解决方案,因为你在整个事务中设计到了本地数据库的操作,所以用lua脚本也很难解决
lua
解决方案,其实你问题中第二种方案,可以解决绝大多数问题
if (redisConnection.exists(key)) { redisConnection.incr(key); } else { //① 这里会出现并发数据库查询value if (redisConnection.setNX(key, value) == 1) {//并发的情况下这里还是会执行多次 return value; } else { return redisConnection.incr(key); } }
唯一的一个问题就是,在首次更新value的时候,可能会在①处出现并发查询数据库的情况.这种方式可以满足绝大多数业务了,如果楼主觉得在首次更新value的时候并发查询数据库,压力实在是太大(一般可能性很小,除非你的业务规模很大),那么只能用分布式锁来觉得了,在①处加一个基于key的分布式锁,
value
key
微信扫码关注PHP中文网服务号
QQ扫码加入技术交流群
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
PHP学习
技术支持
返回顶部
自己琢磨的一个方法,让key和exists过期时间保持一致就行,不知道还有没有更好的方法
如果想把逻辑弄成redis的一个事务做完,弄个lua来做
我的理解是,应该没有完美的方案
如果用@twayne 的方案,在并发的情况下回出现另外一个线程执行到
redisConnection.incr(key),但是redisConnection.setNX(key, value)这步并没有完成用@yuwenbao的
lua脚本解决方案,因为你在整个事务中设计到了本地数据库的操作,所以用lua脚本也很难解决解决方案,其实你问题中第二种方案,可以解决绝大多数问题
唯一的一个问题就是,在首次更新
value的时候,可能会在①处出现并发查询数据库的情况.这种方式可以满足绝大多数业务了,如果楼主觉得在首次更新value的时候并发查询数据库,压力实在是太大(一般可能性很小,除非你的业务规模很大),那么只能用分布式锁来觉得了,在①处加一个基于key的分布式锁,