node关于redis存储问题,redis的调用接口是异步的,如何来保证修改数据的顺序呢
发布于 10 年前 作者 daliniu 10496 次预览 最后一次回复是 10 年前 来自 问答
redis修改数据的时候是先get,之后再set,但是在node中一切都是异步的,也就是说get和set的过程都是异步,既然是异步也就有可能出现 2个请求分别对同一份数据进行修改,都是调用get后再set 第一种情况 get get set set 第二种情况 get set get set 请问如果出现第一种情况的话也就是说第一次修改的结果被第二次修改的结果覆盖,这种情况应该如何解决呢
11 回复
@haozxuan
如果我只看key1 async.waterfall([ function (cb) { foo1(cb); }, function (cb) { foo2(cb); } ], function (err, res) { //do something });
@daliniu 你仔细想想,你说的这种情况,多进程的语言,如PHP,也会遇到。这不是Node异步导致的问题。 如果你一定要保持 get set get set 的顺序,可以使用事务来进行操作。一个事务里面的所有操作能保证原子性。
@daliniu 加全局锁。。。在上个操作未完成前锁定
加watch锁 unwatch解锁
@haozxuan 你好,我想问下载node里面如何加全局锁
@haozxuan
用 promise / q / Async / bluebird 等处理异步回调 不就是了吗
没有这么麻烦,另外 Redis 已经不需要用
WATCH锁了。如果不考虑其他 Event loop 介入,直接用下面的代码即可保证按照
get->set->get->set执行了:如果考虑到其他 Event loop 或者其他 Node 进程并行操作,则可以用 Pipelining 或者 Transaction:
@luinlee Pipelining 或者 Transaction是不是只有ioredis才有,大多数nodejs+redis开发是不是都是使用这种模式的,因为 Event loop 的情况还是存在的
@daliniu Pipelining 和 Transaction 都是 Redis 提供支持的。node_redis 不支持 Pipelining,但是支持 Transaction。如果需要保证顺序,Pipelining 或 Transaction 都可以的。