Какие операции с базами данных выполняли: транзакции или простое чтение и запись
Что проверяют
Работали ли вы с базой глубже, чем session.add() и commit(): где заканчивается транзакция, что будет при ошибке посреди операции и как два конкурентных запроса поделят одну строку. Следом просят конкретный случай из практики и уровень изоляции, на котором он работал.
Как отвечать
Отвечайте от своего проекта, со своими цифрами. Каркас такой:
- чем работали: PostgreSQL или MySQL, драйвер
psycopgилиasyncpg, SQLAlchemy 2.0 или Django ORM, миграции через Alembic или встроенные; - где нужна была транзакция: связанные записи, которые применяются вместе или никак. Заказ, списание остатка, запись в журнал;
- как оформляли: в SQLAlchemy
with Session(engine) as session, session.begin():коммитит на выходе и откатывает при исключении, в Django то же делаетtransaction.atomic(), а вложенныйatomic()ставитSAVEPOINT; - как решали гонки: атомарный
UPDATE stock SET qty = qty - 1 WHERE id = %s AND qty > 0с проверкой числа изменённых строк илиSELECT ... FOR UPDATE(select_for_update()в Django,with_for_update()в SQLAlchemy); - изоляция: у PostgreSQL по умолчанию Read Committed. На
REPEATABLE READиSERIALIZABLEвозможны ошибки сериализации, и транзакцию нужно уметь повторить.
Простое чтение и запись тоже назовите: выборки с пагинацией, пакетная вставка через executemany или COPY, борьба с N+1 через selectinload или select_related.
Если опыт был только с CRUD, скажите прямо и покажите, где транзакция понадобилась бы и как бы вы её оформили. Это сильнее пересказа ACID своими словами.
Где спотыкаются
Перечисляют буквы ACID без примера. Одна история с гонкой за остаток весит больше определений.
Не знают, что драйвер открывает транзакцию сам. psycopg без autocommit начинает её при первом запросе, и забытый commit() оставляет соединение в состоянии «idle in transaction» с висящими блокировками.
Показывают устаревший код: declarative_base из sqlalchemy.ext.declarative и session.query(). В SQLAlchemy 2.0 это DeclarativeBase и запросы через select().