redis和watch + multi允许并发用户

我正在用一个web服务的相同电子邮件地址进行用户注册的负载testing,同时连接的前10个用户将始终注册。

我正在使用WATCH和MULTI,但似乎没有任何工作。

我打电话save()来保存用户。

this.insert = function(callback) { this.preInsert(); created = new Date(); updated = new Date(); // Also with these uncommented it still doesn't work // Common.client.watch("u:" + this.username); // Common.client.watch("em:" + this.email); console.log(ID + " email is locked " + this.email); Common.client.multi() .set("u:" + this.username, ID) .hmset("u:" + ID, {"username": this.username ,"password": this.password ,"email": this.email ,"payment_plan": payment_plan ,"created": created.getTime() ,"updated": updated.getTime() ,"avatar": this.avatar}) .zadd("u:users", 0, ID) .sadd("u:emails", this.email) .set("u:"+ ID + ":stats", 0) .set("em:" + this.email, ID) .exec(); this.postInsert(); if (callback != null) callback(null, this); } this.save = function(callback) { // new user if (ID == -1) { var u = this; Common.client.watch("u:" + this.username); Common.client.exists("u:" + this.username, function(error, exists) { // This username already exists if (exists == 1) { Common.client.unwatch(); if (callback != null) callback({code: 100, message: "This username already exists"}); } else { Common.client.watch("em:" + u.email); Common.client.get("em:" + u.email, function(err, emailExists) { if (emailExists != null) { Common.client.unwatch(); if (callback != null) callback({code: 101, message: "This email is already in use"}); } else { Common.client.incr("u:nextID", function(error, id) { if (error) callback(error); else { ID = id; u.insert(callback); } }); } }); } }); } // existing user else { var u = this; Common.client.get("em:" + this.email, function(err, emailExists) { if (emailExists != ID && emailExists) { if (callback != null) { callback({code: 101, message: "This email is already in use " + ID + " " + emailExists}); } } else { u.update(callback); } }); } } 

输出几乎总是:

 1 email is locked test@test.com 2 email is locked test@test.com 3 email is locked test@test.com 4 email is locked test@test.com 5 email is locked test@test.com 6 email is locked test@test.com 7 email is locked test@test.com 8 email is locked test@test.com 9 email is locked test@test.com 10 email is locked test@test.com 

我做错了什么或者Redis不能处理那么多的并发。 这也是Common的定义:

 var Common = { client: redis.createClient(), ... }; 

是! 经过一晚的rest,当然解决scheme来到我的淋浴。

问题是我使用一个单一的redis线程为整个应用程序,所有的连接注册该线程上的手表。 当然,这并不表示由于没有其他客户端,密钥被不同的客户端修改。

我知道这个线程是8个月大的,但无论如何,我的想法仍然可以帮助别人。 有一个问题,我仍然不明白,我甚至开始自己的线程致力于这个问题Redis的一个客户端 ,我指的是你的。 我现在使用“每个事务的连接”方法,这意味着如果我需要使用WATCH-MULTI-EXEC执行事务,则创build新的连接。 在其他情况下,对于primefaces操作,我使用在应用程序启动期间创build的连接。 不知道这种方法是有效的,因为创build一个新的连接意味着创build+授权,这会产生延迟,但它的工作原理。