Запуск транзакций в Redis

Redis – это открытое in-memory хранилище типа «ключ-значение». Redis позволяет планировать последовательность команд и запускать их одну за другой – такая процедура называется транзакцией. Каждая транзакция рассматривается как непрерывная и изолированная операция, которая обеспечивает целостность данных. Клиенты не могут выполнять команды во время выполнения блока транзакции.

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

Как работать с этим мануалом

Это руководство задумано как шпаргалка с примерами. Его не нужно выполнять последовательно – вы можете просто перейти к любому разделу, который имеет отношение к нужной вам задаче.

Команды, использованные в этом мануале, были протестированы на сервере Ubuntu 18.04 и экземпляре Redis версии 4.0.9. Чтобы настроить аналогичную среду, вы можете следовать разделу 1 руководства Установка и защита Redis в Ubuntu 18.04. Мы покажем, как эти ведут себя команды в redis-cli, интерфейсе командной строки Redis. Обратите внимание, что если вы используете другой интерфейс Redis — например, Redli – то вывод некоторых команд будет отличаться.

Запуск транзакции

Команда multi начинает блок транзакции в Redis. Все последующие команды будут поставлены в очередь до тех пор, пока вы не запустите команду exec, которая выполнит их.

Ниже приведены команды, которые формируют один блок транзакции. Первая команда инициирует транзакцию, вторая устанавливает ключ, содержащий строку со значением 1, третья увеличивает значение на 1, четвертая увеличивает его на 40, пятая возвращает текущее значение строки, а последняя строка выполняет блок транзакции:

multi
set key_MeaningOfLife 1
incr key_MeaningOfLife
incrby key_MeaningOfLife 40
get key_MeaningOfLife
exec

После запуска команды multi интерфейс redis-cli будет отвечать на каждую из следующих команд состоянием QUEUED. Когда вы запустите команду exec, она покажет выходные данные каждой из этих команд по очереди:

1) OK
2) (integer) 2
3) (integer) 42
4) "42"

Команды, включенные в блок, выполняются последовательно в порядке их постановки в очередь. Транзакции Redis являются атомарными: то есть либо обрабатывается каждая команда в блоке транзакции (она принята как валидная и помещена в очередь для выполнения), либо не обрабатывается ни одна из них. Однако даже если команда добавлена ​​в очередь, она все равно может вызвать ошибку при выполнении. В таких случаях другие команды в транзакции все еще будут выполняться, но Redis пропустит вызывающую ошибку команду. Подробнее об ошибках мы поговорим позже.

Отмена транзакции

Чтобы отменить транзакцию, выполните команду discard. Она предотвращает запуск всех ранее поставленных в очередь команд:

multi
set key_A 146
incrby key_A 10
discard
OK

Команда discard возвращает соединение в нормальное состояние, в котором Redis выполняет отдельные команды как обычно. Чтобы сообщить серверу, что вы запускаете новую транзакцию, нужно снова запустить multi.

Ошибки транзакций

Иногда некоторые команды невозможно поставить в очередь – например, команды с синтаксическими ошибками. Если вы попытаетесь поставить в очередь синтаксически неверную команду, Redis вернет ошибку.

Следующая транзакция создает ключ key_A, а затем пытается умножить его на 10. Однако неправильно написанная команда incrby вызывает ошибку и закрывает транзакцию:

multi
set key_A 146
incrbuy key_A 10
(error) ERR unknown command 'incrbuy'

Если вы захотите выполнить команду exec после попытки поставить команду с синтаксической ошибкой в очередь, вы получите другое сообщение об ошибке, где говорится, что транзакция была отклонена:

exec
(error) EXECABORT Transaction discarded because of previous errors.

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

Некоторые недопустимые команды можно поставить в очередь: например, можно запустить команду incr для ключа, содержащего только строку. Поскольку такая команда синтаксически верна, Redis не вернет ошибку, если вы попытаетесь включить ее в транзакцию, и не помешает вам запустить exec. В подобных случаях все остальные команды в очереди будут выполнены, но недопустимая команда вернет ошибку:

multi
set key_A 146
incrby key_A "ten"
exec
1) OK
2) (error) ERR value is not an integer or out of range

Много дополнительной информации о том, как Redis обрабатывает ошибки внутри транзакций, можно найти в официальной документации по этому вопросу.

Заключение

В этом мануале мы разобрали ряд команд для создания, запуска и отмены транзакций в Redis.

Читайте также: Управление наборами в Redis

Tags: , , ,