Istnieje podstawowa cecha jednostek redis MULTI/EXEC, która oznacza, że nie możesz uzyskać wyniki podczas operacji. W związku z tym istnieją dwa popularne sposoby robienia tego, o co prosisz:
- Użyj Lua (
ScriptEvaluate[Async]
); skrypt Lua jest wykonywany na serwerze od początku do końca, jest wydajny i pozwala uniknąć wszelkich problemów związanych z czasem podróży w obie strony (opóźnieniem lub przepustowością) lub konkurencją ze strony innych połączeń - Użyj optymistycznej pętli, która odczytuje bieżącą wartość, a następnie utworzy transakcję w SE-Redis, która dodaje ograniczenie że wartość, którą właśnie odczytałeś, jest taka sama i powoduje efekty uboczne wewnątrz transakcji; biblioteka będzie koordynować niezbędną maszynę WATCH itp., aby uczynić ją solidną, ale jeśli warunek ograniczający okaże się niepoprawny (tj. biblioteka zwróci
false
), musisz wszystko powtórzyć od początku
Szczerze mówiąc, w dzisiejszych czasach zawsze prowadziłbym ludzi do opcji 1; opcja 2 jest tylko "atrakcyjna" (i używam tego terminu całkiem niepoprawnie), jeśli skrypty Lua po stronie serwera nie są dostępne.
Nie jestem przy komputerze, ale zgaduję, że skrypt wyglądałby mniej więcej tak:
local id = redis.call("incr", KEYS[1])
redis.call("hset", KEYS[2], tostring(id), ARGV[1])
return id