Разъяснение использования BEGIN, COMMIT и ROLLBACK в PostgreSQL с помощью sqlAlchemy - PullRequest
0 голосов
/ 05 октября 2018

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

Документация PostgreSQL говорит, что

BEGIN инициирует блок транзакции, то есть все операторы после команды BEGIN будут выполняться в одной транзакции, пока не будет задан явный COMMIT или ROLLBACK.

Таким образом, это означает, что что-либо между BEGIN и COMMIT не будет записано на диск до тех пор, пока все операции не будут успешно завершены.

Однако в некоторых руководствахстатьи, которые я читал об управлении транзакциями в PostgreSQL , как эта , в середине транзакции добавляется SAVEPOINT:

BEGIN;
    UPDATE tbl_Employees
    SET EmpName = 'Grace'
    WHERE EmpID = 4;

SAVEPOINT EmpSave;

    UPDATE tbl_Employees
    SET EmpName = 'Kunal'
    WHERE EmpID = 5;

ROLLBACK TO EmpSave;

Прав ли я предположить, что здесь сотрудникGrace будет обновлено, сотрудник Kunal будет временно обновлен, но затем будет выполнен откат, немедленно возвращающийся к состоянию после обновления Grace?Я знаю, что это игрушечный пример, но когда мне когда-нибудь понадобится SAVEPOINT внутри блока BEGIN и COMMIT, так как все равно обрабатывается как единая атомарная транзакция внутри этого блока?Если бы я хотел постепенно сохранить свой прогресс, я бы просто включил автокоммит?!

Другими словами, я не вижу, как я могу включить ROLLBACK без какой-либо логики, т.е.., если возникает исключение, ROLLBACK, в противном случае продолжить и COMMIT.Почти во всех примерах используется командная строка psql, что не совсем так, как я обычно выполняю SQL-запросы с использованием PG.

Мой первый вопрос: Как реализовать условный ROLLBACK в середине блока BEGIN / COMMIT?Или это даже не нужно, поскольку блок транзакции неявно содержит откат до состояния до BEGIN?

Пока что я нашел единственный способ включить условную логику в * 1041Блок * и COMMIT предназначен для написания моего SQL в другом программном менеджере, например sqlalchemy, используя что-то вроде ниже:

engine = create_engine("...")
Session = sessionmaker(bind=engine)
session = Session()
try:
    item1 = session.query(Item).get(1)
    item2 = session.query(Item).get(2)
    # pending changes are created.
    item1.foo = 'bar'
    item2.bar = 'foo'
    session.commit()
except:
     session.rollback()
     raise
finally:
     session.close()

Мой второй вопрос: Это единственный способ добавить логику вмои ROLLBACK s или COMMIT s программно, используя Python и sqlalchemy (или другой язык)?

...