Проектная лаборатория

Собственный Redis

0 / 124этапов пройдено

Этап 68 · Оптимистическая блокировка

Отслеживание изменений ключей

Русский перевод заданий CodeCrafters. Примеры подготовлены для Go. Выбор языка меняет команды и результаты, но не текст задания.

На этом этапе вы реализуете EXEC и отмену транзакций.

Напоминание о транзакциях Redis

Транзакции Redis позволяют выполнять несколько команд как одну операцию. Основная последовательность:

  1. MULTI — перейти в режим транзакции (реализовано ранее).
  2. SET key value, INCR counter и другие — поставить команды в очередь.
  3. EXEC — выполнить все команды очереди.

Сейчас вы реализуете EXEC и отмену транзакций, если их отслеживаемые ключи изменились.

Команда EXEC

Команда EXEC выполняет все команды, поставленные в очередь после MULTI:

$ redis-cli
> SET foo 100
OK
> MULTI
OK
> SET foo 200
QUEUED
> SET bar 300
QUEUED
> EXEC
1) OK
2) OK

Ответ — массив RESP, каждый элемент которого содержит результат команды в порядке постановки в очередь.

Отмена транзакций с WATCH

Если соединение отслеживает ключи, EXEC должна проверить, не изменил ли другой клиент любой из них между WATCH и EXEC. Если изменил, транзакция отменяется:

Client A: WATCH foo             # Server tracks "foo" for Client A
Client A: MULTI
Client A: SET bar 300           # Queued
Client B: SET foo 999           # Modifies Client A's watched key
Client A: EXEC                  # Returns *-1\r\n, queued commands discarded

EXEC возвращает нулевой массив RESP (*-1\r\n), а команды очереди удаляются без выполнения.

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

Тесты

Тестирующая программа запустит вашу программу так:

$ ./your_program.sh

Она создаст четырёх клиентов и выполнит два сценария.

В первом другой клиент изменяет отслеживаемый ключ:

# Client 1
> SET foo 100        # → +OK
> SET bar 200        # → +OK
> WATCH foo          # → +OK
> MULTI              # → +OK
> SET bar 300        # → +QUEUED
 
# Client 2 modifies the watched key
> SET foo 200        # → +OK
 
# Client 1 tries to execute
> EXEC               # → *-1\r\n (null array, transaction aborted)
> GET bar            # → "200" (unchanged, SET bar 300 was never executed)

Во втором изменяется другой, неотслеживаемый ключ:

# Client 3
> SET baz 100        # → +OK
> SET caz 200        # → +OK
> WATCH baz          # → +OK
> MULTI              # → +OK
> SET caz 400        # → +QUEUED
 
# Client 4 modifies a different key (not the watched one)
> SET caz 300        # → +OK
 
# Client 3 executes successfully
> EXEC               # → array of responses (baz was not modified)
 
# Client 4 verifies the transaction's write took effect
> GET caz            # → "400"

Будет проверено, что:

  • EXEC возвращает нулевой массив RESP (*-1\r\n), если другой клиент изменил отслеживаемый ключ.
  • EXEC возвращает массив результатов команд, если отслеживаемые ключи не менялись.
  • При отмене транзакции команды очереди не выполняются, исходные значения сохраняются.
  • Если отслеживаемые ключи не менялись, команды выполняются и их записи вступают в силу.

Примечания

  • Недостаточно сравнить значение ключа в момент WATCH и EXEC. Если ключ изменили, а потом вернули исходное значение, транзакция всё равно должна отмениться. Отслеживайте факт записи в ключ, а не итоговое отличие значения.
  • После EXEC очищайте состояние наблюдения соединения — ключи и флаг dirty — независимо от успеха или отмены транзакции.

Проверка в вашей IDE

Нужны Node.js, Git, Go 1.24+ для тестеров и инструменты выбранного языка. Тестеры загружаются и запускаются локально; отдельным проектам нужны дополнительные системные зависимости.

Настройка проекта и IDE

1. Создайте проект один раз

node '/opt/graphlms/tools/project-lab/cli.mjs' init redis ./my-redis --language go

2. Откройте папку в IDE

cd ./my-redis

Реализуйте требования этапа в созданном проекте.

Запустите из папки проекта

node '/opt/graphlms/tools/project-lab/cli.mjs' submit --stage mh8

Запускайте submit из папки проекта. Это локальные проверки, а не сертификаты или результаты аккаунта CodeCrafters.

Результат проверки

go / ЛОКАЛЬНО

Подключение к локальной проверке…

Здесь появится результат

Запустите submit в терминале. Страница обновляет результаты каждые 8 секунд.

GraphLMS — инженерная лаборатория роста