← Назад к вопросам
Приведи пример использования транзакции
1.8 Middle🔥 171 комментариев
#Базы данных (SQL)
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
# Транзакции в Python: примеры и лучшие практики
Транзакция — это последовательность операций с базой данных, которые либо все выполняются успешно, либо все откатываются. Рассмотрю несколько практических примеров.
1. Базовая транзакция с psycopg2 (PostgreSQL)
import psycopg2
conn = psycopg2.connect("dbname=test user=postgres")
cur = conn.cursor()
try:
cur.execute("INSERT INTO accounts (name, balance) VALUES (%s, %s)",
("Alice", 1000))
cur.execute("INSERT INTO accounts (name, balance) VALUES (%s, %s)",
("Bob", 500))
conn.commit()
print("✓ Транзакция выполнена")
except Exception as e:
conn.rollback()
print(f"✗ Ошибка: {e}")
finally:
cur.close()
conn.close()
2. Контекстный менеджер (рекомендуется)
import psycopg2
from contextlib import contextmanager
@contextmanager
def get_db_connection():
conn = psycopg2.connect("dbname=test user=postgres")
try:
yield conn
conn.commit()
except Exception:
conn.rollback()
raise
finally:
conn.close()
with get_db_connection() as conn:
cur = conn.cursor()
cur.execute("INSERT INTO orders (user_id, amount) VALUES (%s, %s)", (1, 99.99))
cur.execute("UPDATE accounts SET balance = balance - %s WHERE id = %s", (99.99, 1))
3. SQLAlchemy
from sqlalchemy import create_engine
from sqlalchemy.orm import Session
from models import Account
engine = create_engine('postgresql://user:password@localhost/db')
def transfer_money(from_id: int, to_id: int, amount: float):
with Session(engine) as session:
try:
from_account = session.query(Account).filter_by(id=from_id).with_for_update().one()
to_account = session.query(Account).filter_by(id=to_id).with_for_update().one()
if from_account.balance < amount:
raise ValueError("Недостаточно средств")
from_account.balance -= amount
to_account.balance += amount
session.commit()
return True
except Exception as e:
session.rollback()
print(f"Ошибка перевода: {e}")
return False
4. Async с asyncpg
import asyncpg
async def create_order_async(user_id: int, items: list):
conn = await asyncpg.connect('postgresql://user:password@localhost/db')
async with conn.transaction():
try:
order_id = await conn.fetchval(
'INSERT INTO orders (user_id, created_at) VALUES ($1, NOW()) RETURNING id',
user_id
)
for item in items:
await conn.execute(
'INSERT INTO order_items (order_id, product_id, qty) VALUES ($1, $2, $3)',
order_id, item['product_id'], item['quantity']
)
return order_id
except Exception as e:
print(f"Ошибка: {e}")
raise
finally:
await conn.close()
Ключевые моменты:
- ACID гарантии: Atomicity, Consistency, Isolation, Durability
- Всегда используй try/except/finally или контекстные менеджеры
- SELECT FOR UPDATE для race conditions
- Уровни изоляции: READ UNCOMMITTED → SERIALIZABLE
- Deadlocks: избегай циклических блокировок, заказывай ресурсы в одном порядке
Транзакции критичны для целостности данных в многопользовательских системах.