Транзакция в рамках транзакции

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

У меня есть метод:

def foo():
    session.begin
    try:
          stuffs
    except Exception, e:
         session.rollback()
         raise e
    session.commit()

и метод, который называет первый в транзакции:

def bar():
    stuffs
    try:
         foo()   #<<<< there it is :)
         stuffs
    except Exception, e:
        session.rollback()
        raise e
    session.commit()

если я доберусь и исключение на методе нечто, то все операции будут откатываться? и все остальное будет работать просто великолепно?спасибо!!

8
задан bluefoot 25 February 2010 в 19:28
поделиться

3 ответа

Есть два способа вложить транзакции в SQLAlchemy. Один из них - виртуальные транзакции, где SQLAlchemy отслеживает, сколько начальных операций вы выпустили, и выдает фиксацию только тогда, когда совершается самая внешняя транзакция. Однако откат выполняется немедленно. Поскольку транзакция виртуальная, то есть база данных ничего не знает о вложенности, вы не можете ничего делать с этим сеансом после отката, пока не откатите все внешние транзакции. Чтобы разрешить использование виртуальных транзакций, добавьте аргумент subtransactions = True к вызову begin () . Эта функция существует, чтобы позволить вам использовать управление транзакциями внутри функций, которые могут вызывать друг друга, не отслеживая, находитесь ли вы внутри транзакции или нет. Чтобы это имело смысл, настройте сеанс с autocommit = True и всегда запускайте session.begin (subtransactions = True) в транзакционной функции.

Другой способ вложить транзакции - использовать настоящие вложенные транзакции. Они реализуются с использованием точек сохранения.Если вы откатываете вложенную транзакцию, все изменения, сделанные в этой транзакции, откатываются, но внешняя транзакция остается пригодной для использования, и любые изменения, сделанные внешней транзакцией, остаются. Чтобы использовать выпуск вложенной транзакции session.begin (nested = True) или просто session.begin_nested () . Вложенные транзакции поддерживаются не для всех баз данных. Функция конфигурации библиотеки набора тестов SQLAlchemy sqlalchemy.test.requires.savepoints говорит о поддержке:

    emits_warning_on('mssql', 'Savepoint support in mssql is experimental and may lead to data loss.'),
    no_support('access', 'not supported by database'),
    no_support('sqlite', 'not supported by database'),
    no_support('sybase', 'FIXME: guessing, needs confirmation'),
    exclude('mysql', '<', (5, 0, 3), 'not supported by database')

В PostgreSQL вложенные транзакции SQLAlchemy работают нормально.

18
ответ дан 5 December 2019 в 09:25
поделиться

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

0
ответ дан 5 December 2019 в 09:25
поделиться

В PostgreSQL вложенные транзакции работают нормально.

Что ж, вы не получите ошибки (просто предупреждения), это правда. Но вы не можете зафиксировать внутреннюю транзакцию и откатить внешнюю транзакцию, внешняя транзакция также откатит внутреннюю транзакцию.

НАЧАТЬ;

ВСТАВИТЬ В x (foo) ЗНАЧЕНИЯ ('Джон');

НАЧАТЬ; -- ПРЕДУПРЕЖДЕНИЕ!

INSERT INTO y (bar) VALUES ('Джейн');

COMMIT; - зафиксировать внутреннюю транзакцию

ROLLBACK; - откатит обе вставки, а не только первую, ту, что в таблице «x»

Насколько мне известно, Oracle - одна из немногих, у которых есть эта опция.

0
ответ дан 5 December 2019 в 09:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: