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