Яма Redis: понимание транзакций Redis

Redis

Связанные команды

Заказ Формат эффект вернуть результат
WATCH WATCH key [key ...] дастKeysотметить как监测态, как условие выполнения транзакции always OK.
UNWATCH UNWATCH очистить транзакциюKeysиз监测态, если называетсяEXEC or DISCARD, нет необходимости вручную вызыватьUNWATCH always OK.
MULTI MULTI 显式включиredis事务, с последующимcommandsбудет поставлен в очередь для использованияEXECвыполнять атомарное выполнение always OK.
EXEC EXEC при исполнении сделкиcommandsОчередь, восстановить состояние соединения. еслиWATCHвызывается раньше, только监测серединаKeysКоманда будет выполнена только в том случае, если она не была изменена, в противном случае ее выполнение прекратится (подробности см.CAS机制) успех:Возвращает массив - каждый элемент соответствует одной из атомарных транзакцийcommandрезультат возврата;
Потерпеть поражение:возвращениеNULL(Rubyвозвращение`nil`);
DISCARD DISCARD очистить транзакциюcommandsОчередь, восстановить состояние соединения. еслиWATCHназывается раньше,释放 监测серединаKeys always OK.

Уведомление:

------MULTI,EXEC,DISCARDявляется显式Общие команды для открытия и управления транзакциями, аналогичные关系型数据库серединаBEGAIN,COMMIT,ROLLBACK(на самом деле разрыв огромен);

------WATCHИспользование команды для решения事务并发произведено不可重复读и幻读проблема (просто понимаемая как предоставлениеKey加锁);


Redis-транзакции

MULTI, EXEC, DISCARD и WATCH являются основой транзакций Redis.用来显式开启并控制一个事务,它们允许在一个步骤中执行一组命令. И дает две важные гарантии:

  • Все команды в транзакции сериализуются и выполняются последовательно. Во время выполнения транзакции Redis запросы от другого клиента не поступают. Это гарантирует命令队列Выполняется как одна атомарная операция.
  • Команды в очереди либо все обрабатываются, либо все игнорируются. Команда EXEC запускает выполнение всех команд в транзакции, поэтому, когда клиент теряет соединение с сервером в контексте транзакции,
  • Если это происходит до вызова команды MULTI, ничего не делайте.commands;
  • Если перед этим вызывается команда EXEC, всеcommandsказнены.

В то же время Redis использует AOF (append-only file), используйте доп.write操作Запишите транзакцию на диск. В случае сбоя или сбоя процесса вы можете использовать инструмент redis-check-aof для восстановления файла только для добавления, обеспечения нормального запуска службы и восстановления некоторых операций.


использование

использоватьMULTIЗаказ显式开启Транзакции Redis. Эта команда всегда отвечает OK.此时用户可以发出多个命令,Redis不会执行这些命令,而是将它们排队.EXECПосле вызова все команды будут выполнены. во время звонкаDISCARDМожет清除в делеcommands队列и退出事务.

  • В следующем примере ключи foo и bar атомарно увеличиваются.
>MULTI
OK
>INCR foo
QUEUED
>INCR bar
QUEUED
>EXEC
1)(整数)1
2)(整数)1

Как видно из выполнения вышеуказанной команды,EXECвернуть数组,其中每个元素都是事务中单个命令的返回结果,而且顺序与命令的发出顺序相同. Когда соединение с Redis установленоMULTIВ контексте запроса все команды будут начинаться с字符串QUEUED(Отправлено как ответ о статусе с точки зрения протокола Redis.) в качестве ответа и в命令队列расстановка. Только при вызове EXEC будут выполняться поставленные в очередь команды, после чего真正的返回结果.


ошибка в транзакции

Во время транзакции могут возникнуть два типа командных ошибок:

  • вызовEXECПеред командой была ошибка (COMMANDне удалось поставить в очередь).
  • Например, может существовать команда语法错误(неверное количество аргументов, неправильное имя команды...);
  • или может быть某些关键条件, такие как нехватка памяти (если сервер используетmaxmemoryинструкция выполнена内存限制).

клиент будетEXECОбнаружение первого типа ошибки перед вызовом. Проверяя команду в очереди状态回复(***Примечание: это относится к排队из状态回复, вместо执行结果***), если в команде используетсяQUEUEDчтобы ответить, он правильно поставлен в очередь, иначе Redis вернет ошибку. Если при постановке команды в очередь возникает ошибка, большинство клиентов中止该事务并清除命令队列. Тем не мение:

  • существуетRedis 2.6.5之前, в данном случае вEXECПосле вызова команды клиент выполняет подмножество команд (успешно поставленных в очередь), игнорируя предыдущие ошибки.
  • отRedis 2.6.5开始, сервер запоминает ошибки, возникшие при накоплении команд, когдаEXECПри вызове команды将拒绝执行事务,并返回这些错误,同时自动清除命令队列.
  • Пример выглядит следующим образом:
>MULTI
+OK
>INCR a b c
-ERR wrong number of arguments for 'incr' command

Это потому чтоINCRСинтаксическая ошибка в команде, будет вызванаEXECбыл обнаружен ранее и завершил транзакцию (версия 2.6.5+).

  • вызовEXECПроизошла ошибка после команды.
  • Например, используйте错误的值кkeyвыполнить действие (например,Stringценный вызовListработать)

EXECОшибки, возникающие после выполнения команды, специально не обрабатываются.:即使事务中的某些命令执行失败,其他命令仍会被正常执行.

  • Пример выглядит следующим образом:
>MULTI
+OK
>SET a 3
+QUEUED
>LPOP a
+QUEUED
>EXEC
*2
+OK
-ERR Operation against a key holding the wrong kind of value
  • EXECВозвращает массив строк с двумя элементами, один элементOK, другой-ERR…….
  • Может ли ошибка быть обоснованно возвращена пользователю, зависит от客户端library(как:Spring-data-redis.redisTemplate) собственной реализации.
  • должны знать о том,Даже если команда завершится ошибкой, все остальные команды в очереди будут обработаны ---- Redis не остановит обработку команды.

Транзакции Redis не поддерживают откат (重点)

По фактуRedis命令Может произойти сбой во время выполнения транзакции, но продолжить执行剩余命令вместоRollback(откат транзакции). если вы использовали关系数据库, эта ситуация может показаться вам странной. Однако у этой ситуации есть хорошее объяснение:

  • Redis命令Она может не выполниться просто потому, что был вызван неправильный синтаксис (необнаруженная ошибка при постановке команды в очередь) или операция с неправильным типом данных.Key: Это означает, что фактические неудачные команды вызваны ошибками программирования, которые могут быть обнаружены в процессе разработки и не должны существовать в производственной среде. (Эти замечания полностью отбрасывают вину: «Это все ваши собственные ошибки программирования, и это не имеет никакого отношения к нам».)
  • Так как не нужно поддерживатьRollback,RedisВ салоне чище и эффективнее.

"Что делать, если ошибка произошла только что?"Это反对Redisмнение争论. Однако следует отметить, что в целом откат не спасает от ошибок программирования.Учитывая, что никто не может спасти ошибки программистаRedis命令Тип ошибки, необходимый для сбоя, вряд ли попадет в рабочую среду, поэтому мы выбрали более простой и быстрый подход, который не поддерживает откат.


очистить очередь команд

DISCARDИспользуется для прерывания транзакции. Все команды в транзакции не будут выполнены, и соединение вернется в нормальное состояние.

> SET foo 1
OK
> MULTI
OK
> INCR foo
QUEUED
> DISCARD
OK
> GET foo
"1"