Redis: Почему сценарии Lua заменят транзакции?

В документации по транзакциям говорится:

«мы можем объявить устаревшими и, наконец, удалить транзакции» и «все, что вы можно сделать с транзакцией Redis, вы также можете сделать с скриптом»

http://redis.io/topics/transactions

Но так ли это? Я вижу в этом проблему.

В рамках транзакции вы может НАБЛЮДАТЬ несколько переменных, читать эти переменные, и на основе уникального состояния этих переменных вы можете сделать совершенно другой набор записей перед вызовом EXEC.Если что-то мешает состоянию этих переменных в промежутке времени, EXEC не будет выполнять транзакцию. (Что позволяет вам повторить попытку. Это идеальная система транзакций.)

Сценарий EVAL не позволит вам сделать это. Согласно документации на этой странице:

"Скрипты как чистые функции... Скрипт всегда оценивает одно и то же Команды записи Redis с одинаковыми аргументами для одних и тех же входных данных набор.Операции, выполняемые скриптом, не могут зависеть ни от каких скрытых (неявная) информация или состояние, которое может измениться в сценарии выполнение продолжается или между различными выполнениями скрипта, а также может ли он зависеть от какого-либо внешнего ввода от устройств ввода-вывода?»

http://redis.io/commands/eval

Проблема, которую я вижу с EVAL, заключается в том, что вы не можете ПОЛУЧИТЬ состояние этих переменных внутри сценарий и создать уникальный набор записей на основе состояния этих переменных. Опять же: «Сценарий всегда оценивает одни и те же команды записи Redis с одними и теми же аргументами для одного и того же набора входных данных». Таким образом, результирующие записи уже определены (кэшированы из первый запуск) и скрипт EVAL не заботится о том, какие значения GET находятся внутри скрипта.Единственное, что вы можете сделать, это выполнить GET для этих переменных перед вызовом EVAL, а затем передать эти переменные скрипту EVAL, но вот проблема: теперь у вас есть проблема атомарности между вызовом GET и вызовом EVAL.

Другими словами, все переменные, которые вы бы сделали НАБЛЮДЕНИЕМ за транзакцией, в случае EVAL вместо этого вам нужно получить эти переменные, а затем передать их сценарию EVAL, поскольку атомарный характер scr ipt не гарантируется до тех пор, пока скрипт не запустится, и вам нужно получить эти переменные перед вызовом EVAL для запуска скрипта, что оставляет место, где состояние этих переменных может измениться между GET и их передачей в EVAL. Следовательно, гарантия атомарности, которая есть у вас с WATCH, у вас нет с EVAL для очень важного набора вариантов использования.

Так зачем говорить об отказе от поддержки транзакций, если это приведет к потере важной функциональности Redis? Или на самом деле есть способ сделать это с помощью сценариев EVAL, которые я еще не понимаю? Или запланированы функции, которые могут решить эту проблему для EVAL? (Гипотетический пример: если они заставят WATCH работать с EVAL так же, как WATCH работает с EXEC, это может сработать.)

Есть ли решение этой проблемы? Или я правильно понимаю, что Redis не может быть полностью безопасным для транзакций в долгосрочной перспективе?

15
задан OCDev 10 May 2012 в 10:54
поделиться