场景是这样的:需要对通知未读数量进行缓存。大概有如下三种操作:
这存在一个 BUG ,就是 2 、3 两种操作都没有去检查缓存是否存在,那么当缓存失效之后,直接发生了 2 、3 两种操作的时候,缓存里的这个 “未读数量” 就会变成 1 或者 -1.
现在准备在进行 2 、3 操作的之前,都先进行缓存是否存在的检查。
突然想到,为什么 Redis 不提供 INCR/DECR 缓存不存在的时候,就报错的版本?这样就不用每次都去检查缓存是否存在。只需要处理这个报错,然后再去初始化缓存即可,这样性能不是更好?
1
rrfeng 284 天前
INCR 返回 1 就是不存在
|
2
justdoit123 OP @rrfeng 我也想过这个方法。就是语义没那么明朗。
|
3
Goooooos 284 天前 1
lua 脚本对计数操作,能解决 2 、3
性能不会差太多 |
4
justdoit123 OP @Goooooos 原来 redis 还支持操作~ 谢谢!
|
5
wu00 284 天前 1
检查是否存在在 INCR 会存在并发问题。
只能是封装/重载一个 Increment ,通过 Lua 脚本保证原子性。 ``` public long IncrementIfKeyExists(string key) { var db = redis.GetDatabase(); var script = LuaScript.Prepare("if redis.call('EXISTS', @key) == 1 then return redis.call('INCR', @key) else return nil end"); var result = (long?)db.ScriptEvaluate(script, new { key }); return result ?? 0; } ``` |