Jeśli potrzebujesz wycofania transakcji, polecam użyć czegoś innego niż Redis. Transakcje Redis nie są takie same jak w przypadku innych magazynów danych. Nawet Multi/Exec nie działa tak, jak chcesz — po pierwsze, ponieważ nie ma cofania. Jeśli chcesz wycofać, będziesz musiał ściągnąć obie listy, aby móc je przywrócić - i mam nadzieję, że między naszym stanem błędu a „wycofaniem” żaden inny klient również nie zmodyfikował żadnej z list. Robienie tego w rozsądny i niezawodny sposób nie jest ani trywialne, ani proste. Prawdopodobnie nie byłoby to również dobre pytanie dla SO, ponieważ byłoby bardzo szerokie, a nie specyficzne dla Redis.
Teraz, dlaczego EXEC nie robi tego, co można by pomyśleć. W proponowanym przez Ciebie scenariuszu MULTI/EXEC tylko zajmuje się sprawami:
- Konfigurujesz WATCH, aby upewnić się, że nie nastąpią żadne inne zmiany
- Twój klient umiera przed wydaniem EXEC
- W Redis brakuje pamięci
Całkowicie możliwe jest uzyskanie błędów w wyniku wydania polecenia EXEC. Kiedy wydasz EXEC, Redis wykona wszystkie polecenia w kolejce i zwracają listę błędów. Nie spowoduje to wystąpienia awarii działania add-to-list-1 i add-to-list-2. Nadal miałbyś niezsynchronizowane dwie listy. Kiedy wydajesz, powiedz LPUSH po wydaniu MULTI, zawsze otrzymasz OK
chyba że:
- a) wcześniej dodano zegarek i coś na tej liście zmieniło się lub
- b) Redis zwraca warunek OOM w odpowiedzi na oczekujące polecenie push
DISCARD nie działa tak, jak niektórzy mogą myśleć. DISCARD jest używane zamiast EXEC, a nie jako mechanizm wycofywania. Po wydaniu EXEC transakcja jest zakończona. Redis nie ma żadnego mechanizmu wycofywania — nie o to chodzi w transakcji Redis.
Kluczem do zrozumienia, co Redis nazywa transakcjami, jest uświadomienie sobie, że są one zasadniczo kolejką poleceń na poziomie połączenia klienta. Nie są maszyną stanu bazy danych.