4

Playing with nodejs, socket.io and redis transaction.
Wondering what would happen with this code (dummy code)

var redis = require('redis');  
var client = redis.createClient();  

...  

socket.on('setSomeKey', function() {  
    client.watch('someKey');
    client.get('someKey',function(err,replies) {  
        client.multi().set('someKey','someValue').exec();
    });
});

socket.on('setSomeStuff', function() {
    client.watch('someStuff');
    client.set('someStuff','blip');
    ...
});

Client 1 sends event 'setSomeKey':
-> redis watch someKey
-> redis get someKey and wait for reply

Client 2 sends event 'setSomeStuff'
-> redis watch someStuff
-> redis set someStuff & wait for reply

Client 1: -> receives 'someKey' and try multi..exec:
=> will the watch on 'someStuff' set by client2 impact the multi exec ?

In other words, could this happens while watching redis with MONITOR:
- watch someKey
- get someKey
- watch someStuff
- set someStuff
- multi
- exec => FAIL because of "watch someStuff" which has change between get and multi..exec executed in the callback ?

Nihau
  • 474
  • 3
  • 20
  • Did you get an answer to this? I'm pretty sure it messes things up. Currently having the same 'issue' – Geert-Jan Oct 28 '14 at 09:27
  • I didn't but here's two alternatives to optimistic lock: - implement pessimistic lock via SET .. NX as described here http://redis.io/commands/set or use lua scripting (all actions inside a script are atomic) – Nihau Jan 20 '15 at 23:15
  • With some new insight I can confidently say that pessimistic locking is not needed. You can still have optimistic locking, but you need to make sure every piece of concurrent running code that uses WATCH uses it's own connection. This will not cause any problems downstream since Redis Server itself is single-threaded. However, it allows to circumvent the stuff described in the question. – Geert-Jan Jan 21 '15 at 10:07

0 Answers0