Транзакции и менеджеры контекста
Безопасно фиксируйте и откатывайте изменения
«Транзакции и менеджеры контекста» — бесплатный урок Python Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Python Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Python Academy содержит 4 уроков всего.
Что такое транзакция
Транзакция объединяет несколько инструкций, поэтому они либо все выполняются успешно, либо все завершаются неудачей. Это поддерживает согласованность данных.
SQLite автоматически начинает транзакцию перед инструкциями, изменяющими данные.
import sqlite3
conn = sqlite3.connect(':memory:')
cur = conn.cursor()
cur.execute('CREATE TABLE accounts (id INTEGER PRIMARY KEY, balance INTEGER)')
print('Table ready for transactions')
conn.close()Сохранение с помощью commit
Изменения не становятся постоянными, пока Вы не вызовете conn.commit(). До этого они существуют только в текущей транзакции.
import sqlite3
conn = sqlite3.connect(':memory:')
cur = conn.cursor()
cur.execute('CREATE TABLE accounts (id INTEGER PRIMARY KEY, balance INTEGER)')
cur.execute('INSERT INTO accounts (balance) VALUES (100)')
conn.commit()
print('Committed')
conn.close()Откат изменений
conn.rollback() отменяет все изменения после последней фиксации. Используйте его, если что-то пошло не так.
import sqlite3
conn = sqlite3.connect(':memory:')
cur = conn.cursor()
cur.execute('CREATE TABLE accounts (id INTEGER PRIMARY KEY, balance INTEGER)')
conn.commit()
cur.execute('INSERT INTO accounts (balance) VALUES (100)')
conn.rollback()
cur.execute('SELECT COUNT(*) FROM accounts')
print('Rows after rollback:', cur.fetchone()[0])
conn.close()Перевод денежных средств
Транзакции особенно полезны, когда несколько обновлений должны оставаться согласованными. При банковском переводе средства вычитаются с одного счёта и зачисляются на другой. Должны произойти оба действия или ни одного.
import sqlite3
conn = sqlite3.connect(':memory:')
cur = conn.cursor()
cur.execute('CREATE TABLE accounts (id INTEGER PRIMARY KEY, balance INTEGER)')
cur.execute('INSERT INTO accounts (id, balance) VALUES (1, 100)')
cur.execute('INSERT INTO accounts (id, balance) VALUES (2, 50)')
cur.execute('UPDATE accounts SET balance = balance - 30 WHERE id = 1')
cur.execute('UPDATE accounts SET balance = balance + 30 WHERE id = 2')
conn.commit()
cur.execute('SELECT id, balance FROM accounts')
print(cur.fetchall())
conn.close()Обработка ошибок с помощью try/except
Оберните транзакцию в try/except. При ошибке выполните откат, чтобы частичные изменения не повредили данные.
import sqlite3
conn = sqlite3.connect(':memory:')
cur = conn.cursor()
cur.execute('CREATE TABLE accounts (id INTEGER PRIMARY KEY, balance INTEGER)')
try:
cur.execute('INSERT INTO accounts (id, balance) VALUES (1, 100)')
cur.execute('INSERT INTO accounts (id, balance) VALUES (1, 200)')
conn.commit()
except sqlite3.IntegrityError:
conn.rollback()
print('Rolled back after error')
conn.close()Соединение как контекстный менеджер
Использование with conn: автоматически фиксирует изменения при успехе и выполняет откат, если внутри блока возникает исключение.
import sqlite3
conn = sqlite3.connect(':memory:')
conn.execute('CREATE TABLE accounts (id INTEGER PRIMARY KEY, balance INTEGER)')
with conn:
conn.execute('INSERT INTO accounts (balance) VALUES (100)')
print('Auto-committed via with block')
conn.close()Автоматический откат при исключении
Если в блоке with conn: возникает исключение, транзакция автоматически откатывается. Обратите внимание: само соединение остаётся открытым.
import sqlite3
conn = sqlite3.connect(':memory:')
conn.execute('CREATE TABLE accounts (id INTEGER PRIMARY KEY)')
try:
with conn:
conn.execute('INSERT INTO accounts (id) VALUES (1)')
conn.execute('INSERT INTO accounts (id) VALUES (1)')
except sqlite3.IntegrityError:
print('Block rolled back automatically')
count = conn.execute('SELECT COUNT(*) FROM accounts').fetchone()[0]
print('Rows:', count)
conn.close()closing() для соединения
Вспомогательная функция contextlib.closing гарантирует вызов close() при завершении блока и освобождает соединение.
import sqlite3
from contextlib import closing
with closing(sqlite3.connect(':memory:')) as conn:
conn.execute('CREATE TABLE t (id INTEGER)')
print('Used inside closing()')
print('Connection closed automatically')Сочетание обоих шаблонов
Поместите with conn: внутрь closing(...), чтобы одновременно управлять транзакцией и гарантировать закрытие соединения.
import sqlite3
from contextlib import closing
with closing(sqlite3.connect(':memory:')) as conn:
conn.execute('CREATE TABLE t (id INTEGER, v TEXT)')
with conn:
conn.execute('INSERT INTO t VALUES (1, ?)', ('hello',))
print(conn.execute('SELECT * FROM t').fetchall())isolation_level
Свойство isolation_level соединения определяет, когда начинаются транзакции. Значение по умолчанию позволяет SQLite управлять ими; установка значения None включает режим автоматической фиксации.
import sqlite3
conn = sqlite3.connect(':memory:')
print('Default isolation_level:', repr(conn.isolation_level))
conn.isolation_level = None
print('Now autocommit:', conn.isolation_level)
conn.close()Почему транзакции важны
Без транзакций сбой в середине обновления может оставить данные изменёнными лишь наполовину. Транзакции делают набор изменений атомарным, то есть неделимым. Это защищает целостность данных.
import sqlite3
conn = sqlite3.connect(':memory:')
conn.execute('CREATE TABLE log (msg TEXT)')
with conn:
conn.execute('INSERT INTO log VALUES (?)', ('all or nothing',))
print('Atomic write done')
conn.close()Быстрая проверка
Проверьте свои знания о транзакциях.
Итоги
Вы научились безопасно управлять транзакциями.
commit()сохраняет изменения, аrollback()отменяет их- Оберните потенциально опасные операции записи в
try/exceptс откатом with conn:автоматически фиксирует изменения или выполняет откатcontextlib.closingгарантирует закрытие соединения
Часто задаваемые вопросы
Урок «Транзакции и менеджеры контекста» бесплатный?
Да — полный текст урока «Транзакции и менеджеры контекста» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Python Academy, подпишись на CoddyKit PRO. Курс Python Academy содержит 4 уроков всего.
Чему я научусь в уроке «Транзакции и менеджеры контекста»?
Безопасно фиксируйте и откатывайте изменения Ты практикуешь Python Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Python Academy?
Предыдущий опыт не требуется. Python Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.
Сколько времени занимает урок «Транзакции и менеджеры контекста»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Python Academy?
Да. Каждый урок Python Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Подключение и создание таблиц
- Insert, Select, Update, Delete
- Параметризованные запросы
- Транзакции и менеджеры контекста