2015-12-26 4 views
0

Il me semble que l'utilisation de IF ferait échouer l'instruction si elle était réessayée. Par conséquent, la déclaration n'est pas idempotente. Par exemple, étant donné la CQL ci-dessous, si elle échoue à cause d'un problème de délai d'attente ou de système et que je réessaye, cela peut ne pas fonctionner car une autre personne peut avoir mis à jour la version entre les tentatives.Est-ce que CQL3 "IF" rend ma mise à jour non idempotente?

UPDATE users 
SET name = 'foo', version = 4 
WHERE userid = 1 
IF version = 3 

Meilleures pratiques pour les mises à jour de Cassandra sont mises à jour pour faire idempotent, mais l'opérateur IF est en opposition directe à ce sujet. Est-ce que je manque quelque chose?

Répondre

1

Cette question est plus sur la linéraire (commande) que l'idempotence je pense. Cette requête utilise Paxos pour essayer de déterminer l'état du système avant d'appliquer une modification. Si l'état du système est identique, la requête peut être réessayée plusieurs fois sans modification des résultats. Ceci fournit une forme faible de commande (et est chère) contrairement à la plupart des écritures de Cassandra. En général, vous ne devez utiliser les opérations CAS que si vous tentez d'enregistrer l'état d'un système (plutôt qu'un historique ou un journal)

N'utilisez pas beaucoup de ces requêtes si vous pouvez l'aider, les directives suggèrent de n'avoir qu'un petit pourcentage de vos requêtes s'appuient sur ce comportement.

2

Si votre application est idempotente, vous n'aurez généralement pas besoin d'utiliser la clause IF coûteuse, car tous vos clients essaieront de définir la même valeur. Par exemple, supposons que vos clients ont agrandi certaines valeurs et écrit le résultat dans une table de déploiement. Chaque client calcule le même total et écrit la même valeur, donc peu importe si plusieurs clients lui ont écrit, ou quel ordre ils lui ont écrit, car ce serait la même valeur.

Si vous recherchez réellement une exclusion mutuelle, telle que le maintien d'un solde bancaire, la clause IF peut être utilisée. Vous pouvez lire une ligne pour obtenir le solde actuel, puis soustraire de l'argent et mettre à jour le solde uniquement si le solde n'a pas changé depuis que vous l'avez lu. Si un autre client essayait d'ajouter un dépôt en même temps, alors il échouerait et devrait essayer à nouveau. Une autre manière de le faire sans exclusion mutuelle consiste à écrire chaque retrait et dépôt comme une ligne de transaction groupée séparée, puis à calculer le solde comme résultat idempotent de l'application de toutes les lignes de transaction.

Vous pouvez utiliser la clause IF pour les écritures idempotentes, mais cela semble inutile. Le premier client à faire l'écriture réussirait et Cassandra retournerait la valeur "appliqué = Vrai". Et le prochain client à essayer la même écriture reviendrait "appliqué = Faux, version = 4", indiquant que la ligne avait déjà été mise à jour à la version 4, donc rien n'a été changé.