Транзакции и изоляция: как не устроить дедлоки и грязные чтения
Коллеги, давайте разберем план выполнения. Транзакция — это не «обернул в BEGIN и забыл», а контракт на время удержания блокировок, версию данных и цену ошибки.
Базовые правила простые:
— держите транзакцию короткой; все внешние вызовы, API и пользовательский ввод — до BEGIN или после COMMIT
— не смешивайте чтение и долгие вычисления внутри одной транзакции
— пишите в одном и том же порядке таблицы и строки, иначе привет дедлок
— уровень изоляции выбирайте по конфликту, а не «чтобы было надежнее»
READ COMMITTED обычно хватает для большинства OLTP: он режет грязные чтения и не тащит лишние блокировки. REPEATABLE READ и SERIALIZABLE дают больше гарантий, но платите за это ожиданиями, ростом contention и сюрпризами на пиках нагрузки. Схема простая, но дьявол кроется в статистике: если запросы стали медленнее, транзакция держит блокировки дольше, и вся очередь начинает гореть 🔥
Золотое правило: сначала мониторинг, потом индексы. Смотрите не только на время запроса, но и на wait events, deadlocks, lock escalation, количество ретраев и размер транзакций.
Если нужна строгая согласованность, используйте ее точечно. В продакшене так лучше не делать, и вот почему: «максимальная изоляция» на весь сервис почти всегда превращается в медленный сервис с очередями.
Оптимизация производительности баз
@database_performance_tuning_arb
Транзакции и изоляция: как не устроить дедлоки и грязные чтения
Этот пост опубликован в Telegram-канале Оптимизация производительности баз. Подписаться можно по ссылке: @database_performance_tuning_arb.