redis - как создать перевод - PullRequest
       51

redis - как создать перевод

0 голосов
/ 18 января 2019

Фон

Мне нужен способ создания транзакции в REDIS, где в случае сбоя одной команды мне нужна вся транзакция для сбоя / отката.

Я пытался один раз спросить ( REDIS - конвейер не завершится ошибкой, если одна из команд не работает )

Но, возможно, я не спросил четко или что-то потеряно в формулировке моего вопроса. Или я не поняла ответ. Но в любом случае я проводил больше исследований, и кажется, что REDIS действительно имеет транзакции с помощью команд MULTI и EXEC. И в моем случае, поскольку я использую pyredis, я могу создать конвейер с параметром «транзакция», установленным в «Истина».

Код

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

@application.route("/test/transactions/<int:trigger>")
def test_transactions(trigger):
    try:
        logging.info('test transactions triggered')
        r = redis.Redis(connection_pool=POOL)
        p = r.pipeline(transaction=True)
        p.hmset('multitest', {'thefield':'thevalue'})
        if trigger==1:  
            assert 1==0, "trigger enabled. this will cause failure."
        p.hmset('multitest2', {'a':'b'})
        retval = p.execute()
        logging.info(retval)
        return "keys created"
    except Exception as e:
        logging.error(e)
        return "keys not created"

Когда я передаю 0 как триггер, он не "отказывает", поэтому система создает оба хэша. Когда я устанавливаю триггер, он, кажется, работает правильно, потому что у меня нет хэшей в базе данных.

Вопросы

  1. это хороший тест? доказали, что транзакции работают? Если нет, можете ли вы предложить лучше проверить?

  2. В моем реальном коде я планирую проверить содержимое retval (которое, кстати, будет выглядеть примерно так: [0,0], если ничего не было сделано, или [1, 1], если я что-то добавил / удалил.) Если я ожидаю [1,1] и получаю что-то другое, я собираюсь предположить, что транзакция не удалась, и метод просто возвращает false. Есть лучший способ сделать это?

Заранее спасибо за ваше время и вклад.

1 Ответ

0 голосов
/ 19 января 2019

Транзакции Redis не имеют возможности «отката» - как только вы вызовете p.execute(), операции в нем будут выполнены. Вы можете отменить транзакцию в любое время до ее исполнения, позвонив по номеру p.discard().

.

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

@application.route("/test/transactions/<int:trigger>")
def test_transactions(trigger):
    try:
        logging.info('test transactions triggered')
        r = redis.Redis(connection_pool=POOL)
        p = r.pipeline(transaction=True)
        p.hmset('multitest', {'thefield':'thevalue'})
        if trigger==1:  
            p.discard()
            return "discarded"
        else:
            p.hmset('multitest2', {'a':'b'})
            retval = p.execute()
            logging.info(retval)
            return "keys created"
    except Exception as e:
        logging.error(e)

Примечание: я не получаю ваш код полностью - вы можете проверить trigger перед чем-либо и пропустить попытку совершить сделку.

...