Метод begin_nested
Метод begin_nested класса Connection
открывает вложенную транзакцию, которая в большинстве
СУБД реализуется через механизм SAVEPOINT.
Вложенная транзакция может быть откатана отдельно
от внешней, что позволяет частично отменять изменения,
не прерывая всю транзакцию целиком. Метод не принимает
обязательных параметров и возвращает объект
NestedTransaction, который поддерживает контекстный
менеджер и методы commit и rollback.
Метод begin_nested можно вызывать только внутри
уже начатой транзакции. Если транзакция ещё не открыта,
SQLAlchemy автоматически начнёт внешнюю транзакцию.
Вложенные транзакции могут быть вложены друг в друга
на произвольную глубину, если это поддерживает диалект.
Синтаксис
Connection.begin_nested()
Пример
Давайте откроем внешнюю транзакцию и создадим внутри неё вложенную, а затем откатим только вложенную:
from sqlalchemy import create_engine, text
engine = create_engine('sqlite:///:memory:')
with engine.connect() as conn:
with conn.begin():
conn.execute(text('CREATE TABLE articles (id INTEGER, title TEXT)'))
conn.execute(text("INSERT INTO articles VALUES (1, 'article 1')"))
with conn.begin_nested():
conn.execute(text("INSERT INTO articles VALUES (2, 'article 2')"))
res = conn.execute(text('SELECT * FROM articles'))
print(res.fetchall())
Результат выполнения кода:
[(1, 'article 1')]
Пример
Давайте явно откатим вложенную транзакцию методом
rollback:
from sqlalchemy import create_engine, text
engine = create_engine('sqlite:///:memory:')
with engine.connect() as conn:
with conn.begin():
conn.execute(text('CREATE TABLE articles (id INTEGER, title TEXT)'))
conn.execute(text("INSERT INTO articles VALUES (1, 'article 1')"))
nested = conn.begin_nested()
conn.execute(text("INSERT INTO articles VALUES (2, 'article 2')"))
nested.rollback()
res = conn.execute(text('SELECT * FROM articles'))
print(res.fetchall())
Результат выполнения кода:
[(1, 'article 1')]
Пример
Давайте зафиксируем вложенную транзакцию методом
commit, чтобы сохранить изменения внутри
внешней транзакции:
from sqlalchemy import create_engine, text
engine = create_engine('sqlite:///:memory:')
with engine.connect() as conn:
with conn.begin():
conn.execute(text('CREATE TABLE articles (id INTEGER, title TEXT)'))
nested = conn.begin_nested()
conn.execute(text("INSERT INTO articles VALUES (1, 'article 1')"))
nested.commit()
res = conn.execute(text('SELECT * FROM articles'))
print(res.fetchall())
Результат выполнения кода:
[(1, 'article 1')]
Пример
Давайте создадим две вложенные транзакции и откатим только внутреннюю:
Результат выполнения кода:
[(1, 'article 1')]
Смотрите также
-
класс
Connection,
который представляет соединение с базой данных -
метод
begin,
который открывает внешнюю транзакцию -
метод
commit,
который фиксирует текущую транзакцию -
метод
rollback,
который откатывает текущую транзакцию