Redis
 sql >> база данни >  >> NoSQL >> Redis

Транзакции и извлечение за гледане в Redis

Тук има няколко въпроса.

1) Защо не можем да изпълним увеличение на транзакцията, която не може да бъде прекъсната от друга команда?

Моля, обърнете внимание първо, че „транзакциите“ на Redis са напълно различни от това, което повечето хора смятат за транзакции в класическата СУБД.

# Does not work
redis.multi() 
current = redis.get('powerlevel') 
redis.set('powerlevel', current + 1) 
redis.exec()

Трябва да разберете какво се изпълнява от страна на сървъра (в Redis) и какво се изпълнява от страна на клиента (във вашия скрипт). В горния код командите GET и SET ще се изпълняват от страната на Redis, но присвояването на тока и изчисляването на тока + 1 трябва да се изпълняват от страна на клиента.

За да се гарантира атомарност, MULTI/EXEC блок забавя изпълнението на Redis команди до exec. Така клиентът само ще трупа командите GET и SET в паметта и ще ги изпълни с един изстрел и в крайна сметка атомарно. Разбира се, опитът за присвояване на ток към резултата от GET и увеличението ще се случи доста по-рано. Всъщност методът redis.get ще върне само низа „QUEUED“, за да сигнализира, че командата е забавена и увеличаването няма да работи.

В MULTI/EXEC блоковете можете да използвате само команди, чиито параметри могат да бъдат напълно известни преди началото на блока. Може да искате да прочетете документацията за повече информация.

2) Защо трябва да повторим вместо това и да изчакаме, докато никой не промени стойността, преди транзакцията да започне?

Това е пример за едновременен оптимистичен модел.

Ако не използвахме WATCH/MULTI/EXEC, щяхме да имаме потенциално условие за състезание:

# Initial arbitrary value
powerlevel = 10
session A: GET powerlevel -> 10
session B: GET powerlevel -> 10
session A: current = 10 + 1
session B: current = 10 + 1
session A: SET powerlevel 11
session B: SET powerlevel 11
# In the end we have 11 instead of 12 -> wrong

Сега нека добавим блок WATCH/MULTI/EXEC. С клауза WATCH командите между MULTI и EXEC се изпълняват само ако стойността не е променена.

# Initial arbitrary value
powerlevel = 10
session A: WATCH powerlevel
session B: WATCH powerlevel
session A: GET powerlevel -> 10
session B: GET powerlevel -> 10
session A: current = 10 + 1
session B: current = 10 + 1
session A: MULTI
session B: MULTI
session A: SET powerlevel 11 -> QUEUED
session B: SET powerlevel 11 -> QUEUED
session A: EXEC -> success! powerlevel is now 11
session B: EXEC -> failure, because powerlevel has changed and was watched
# In the end, we have 11, and session B knows it has to attempt the transaction again
# Hopefully, it will work fine this time.

Така че не е нужно да повтаряте, за да чакате, докато никой не промени стойността, а по-скоро да опитвате операцията отново и отново, докато Redis се увери, че стойностите са последователни и сигнализира, че е успешна.

В повечето случаи, ако „транзакциите“ са достатъчно бързи и вероятността да има спор е малка, актуализациите са много ефективни. Сега, ако има спор, ще трябва да се направят някои допълнителни операции за някои "транзакции" (поради итерацията и повторните опити). Но данните винаги ще бъдат последователни и не се изисква заключване.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Как да използвате Redis хешове

  2. Стартирайте redis-сървъра с конфигурационен файл

  3. Node.js, (Hi)Redis и командата multi

  4. Как да премахна ключовете?

  5. Как да експортирате Redis ключове като CSV с помощта на CLI