×
Мы обрабатываем cookies, чтобы сделать наш сайт удобнее и персонализированнее для вас. Подробнее: политика использования «cookies» и «политики конфиденциальности».

Для самостоятельной настройки ознакомьтесь с инструкцией

Дополнительные настройки cookies в браузерах

Файлы cookie автоматически загружаются в ваш браузер при посещении веб-сайта. У вас есть возможность управлять этими файлами. Если Вы не согласны с использованием файлов cookies, запретите их сохранение на своём устройстве, удалите уже имеющиеся файлы cookies через настройки браузера или прекратите использование сайта.

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

Инструкция по отключению cookies
Принять
Настроить
Отклонить

ДОКУМЕНТАЦИЯ

Выберите версию, форк и язык для СУБД Digital Q.DataBase, чтобы прочитать или скачать всю документацию.
Техподдержка
Документация
Диасофт
Авторские права © 2016–2025 ООО "Диасофт Экосистема"
Скачать всю документацию:

5.9.7. Явные подтранзакции

5.9.7.1. Контекстные менеджеры подтранзакций

Восстановление после ошибок, вызванных доступом к базе данных, как описано в Раздел 5.9.6.2 может привести к нежелательной ситуации, когда часть операций завершается успешно до возникновения сбоя в одной из них, и после восстановления после этой ошибки данные остаются в несогласованном состоянии. PL/Python предлагает решение этой проблемы в виде явных подтранзакций.

5.9.7.1. Контекстные менеджеры подтранзакций #

Рассмотрим функцию, реализующую перевод средств между двумя счетами:

CREATE FUNCTION transfer_funds() RETURNS void AS $$
try:
    plpy.execute("UPDATE accounts SET balance = balance - 100 WHERE account_name = 'joe'")
    plpy.execute("UPDATE accounts SET balance = balance + 100 WHERE account_name = 'mary'")
except plpy.SPIError as e:
    result = "error transferring funds: %s" % e.args
else:
    result = "funds transferred correctly"
plan = plpy.prepare("INSERT INTO operations (result) VALUES ($1)", ["text"])
plpy.execute(plan, [result])
$$ LANGUAGE plpython3u;

Если второй UPDATE оператор приведет к возникновению исключения, функция сообщит об ошибке, однако результат выполнения первого UPDATE будет тем не менее зафиксирован. Другими словами, средства будут списаны со счета Джо, но не будут переведены на счет Мэри.

Чтобы избежать подобных проблем, вы можете обернуть plpy.execute вызовы в явную подтранзакцию. Модуль plpy предоставляет вспомогательный объект для управления явными подтранзакциями, создаваемый с помощью plpy.subtransaction() . Объекты, создаваемые этой функцией, реализуют интерфейс менеджера контекста. Используя явные подтранзакции, мы можем переписать функцию следующим образом:

CREATE FUNCTION transfer_funds2() RETURNS void AS $$
try:
    with plpy.subtransaction():
        plpy.execute("UPDATE accounts SET balance = balance - 100 WHERE account_name = 'joe'")
        plpy.execute("UPDATE accounts SET balance = balance + 100 WHERE account_name = 'mary'")
except plpy.SPIError as e:
    result = "error transferring funds: %s" % e.args
else:
    result = "funds transferred correctly"
plan = plpy.prepare("INSERT INTO operations (result) VALUES ($1)", ["text"])
plpy.execute(plan, [result])
$$ LANGUAGE plpython3u;

Обратите внимание, что использование try/except по-прежнему требуется. В противном случае исключение распространится до вершины стека Python, что приведет к аварийному завершению всей функции с Digital Q.DataBase ошибкой, и в таблицу operations не будет добавлено ни одной строки. Диспетчер контекста подтранзакции не перехватывает ошибки; он лишь гарантирует, что все операции с базой данных, выполненные в его области действия, будут атомарно зафиксированы или откачены. Откат блока подтранзакции происходит при любом выходе по исключению, а не только при ошибках, возникающих при доступе к базе данных. Обычное исключение Python, возбужденное внутри явного блока подтранзакции, также приведет к откату этой подтранзакции.

Наверх
свяжитесь
с нами
контакты
Для прямой связи с нами вы можете использовать контакты ниже, либо оставить заявку через форму обратной связи, и мы обязательно свяжемся с вами

*поля обязательные к заполнению