Se você precisar de reversão de transação, recomendo usar algo diferente do Redis. As transações do Redis não são as mesmas de outros datastores. Mesmo o Multi/Exec não funciona para o que você deseja - primeiro porque não há reversão. Se você quiser reversão, terá que baixar ambas as listas para poder restaurar - e esperar que entre nossa condição de erro e a "reversão" nenhum outro cliente também modifique nenhuma das listas. Fazer isso de forma sã e confiável não é trivial, nem simples. Provavelmente também não seria uma boa pergunta para o SO, pois seria muito ampla e não específica do Redis.
Agora, por que EXEC não faz o que se poderia pensar. No cenário proposto MULTI/EXEC somente atende os casos de:
- Você configura RELÓGIOS para garantir que nenhuma outra alteração ocorra
- Seu cliente morre antes de emitir EXEC
- O Redis está sem memória
É perfeitamente possível obter erros como resultado da emissão do comando EXEC. Ao emitir EXEC, o Redis executará todos comandos na fila e retornar uma lista de erros. Ele não fornecerá o caso de o add-to-list-1 funcionar e o add-to-list-2 falhar. Você ainda teria suas duas listas fora de sincronia. Ao emitir, digamos um LPUSH após emitir MULTI, você sempre receberá um
OK
a não ser que tu:- a) adicionou um relógio anteriormente e algo nessa lista foi alterado ou
- b) Redis retorna uma condição OOM em resposta a um comando push enfileirado
O DISCARD não funciona como alguns podem pensar. DISCARD é usado em vez de EXEC, não como um mecanismo de reversão. Assim que você emitir o EXEC, sua transação estará concluída. O Redis não possui nenhum mecanismo de reversão - não é disso que se trata a transação do Redis.
A chave para entender o que o Redis chama de transações é perceber que elas são essencialmente uma fila de comandos no nível de conexão do cliente. Eles não são uma máquina de estado do banco de dados.