2013-08-26 5 views
3

En utilisant Redis, je souhaite exécuter une séquence atomique de commandes, c'est-à-dire que je dois garantir qu'aucun autre client n'effectuera de modifications dans la base de données pendant l'exécution de la séquence.Transactions en Redis avec des opérations de lecture

Si j'utilisé écrire commandes seulement, je pouvais utiliser des instructions MULTI et EXEC pour assurer atomicité en utilisant les transactions. Cependant, je voudrais également utiliser lire commandes dans mes transactions. Par conséquent, je ne peux pas utiliser MULTI, car les commandes de lecture sont également mises en file d'attente!

Fondamentalement, de manière atomique, je dois faire ce qui suit:

  1. Lire x de la base de données,
  2. Basé sur x, magasin f(x) à la base de données.

Les deux parties 1. et 2. doivent faire partie d'une seule transaction atomique.

Existe-t-il un moyen simple de faire cela?

+0

Vous pouvez essayer d'utiliser les scripts Lua: http://redis.io/commands/eval –

Répondre

9

Il existe deux bonnes solutions à votre problème.

Option 1:

Vous devez émettre un WATCH sur la clé que vous lisez à partir. Votre transaction ressemblerait à quelque chose comme ceci:

WATCH x 
x = GET x 
MULTI 
SET y, f(x) 
EXEC 

Dans cet exemple, les commandes d'écriture à l'intérieur du bloc plusieurs seront exécutés atomiquement, mais que si n'a pas changé la valeur de x clé depuis WATCH a été appelée. C'est ce qu'on appelle un verrou optimiste. Si la valeur de x change votre application obtiendra une erreur et devra décider quoi faire ensuite, qui est susceptible d'essayer à nouveau en utilisant la nouvelle valeur de x.

Option 2:

Redis prend désormais en charge les scripts Lua, et les scripts LUA sont exécutés atomiquement. Si vous pouvez encapsuler votre logique dans un script lua, vous pouvez lire votre clé, lancer votre logique f(x), et stocker le résultat, le tout de manière atomique. Cela peut être difficile ou même une non-option en fonction de la logique que vous effectuez. Vous devrez peut-être même faire de vilains hacks comme passer des valeurs à lua en les codant en dur directement dans le script que vous voulez exécuter. Cela dit, si vous le faites fonctionner cette méthode devrait être fiable et performante, et vous n'avez pas à faire face à des échecs de gestion EXEC.

+0

L'option 1 est parfaite pour mes besoins car la réitération itérative de l'opération semble être une solution raisonnable. Actuellement, ma logique d'application est beaucoup plus complexe par rapport à l'exemple que j'ai fourni, mais je vais certainement jeter un oeil à Lua. Merci beaucoup! – Tregoreg

Questions connexes