Транзакции и изоляция: как не словить грязное чтение, блокировки и дедлоки
Коллеги, давайте разберем план выполнения. Транзакция — это не «обернул запросы и стало надежно», а контракт между консистентностью и ценой этой консистентности. Чем выше уровень изоляции, тем меньше сюрпризов в данных, но тем охотнее система держит блокировки и режет параллелизм.
Базовое правило простое: выбирайте самый слабый уровень, который еще сохраняет бизнес-смысл. Для отчетов часто хватает snapshot/consistent read; для критичных списаний и остатков нужны явные проверки и короткие транзакции. Не держите транзакцию открытой ради логики приложения, сетевых вызовов и чужих API — в продакшене так лучше не делать, и вот почему: вы превращаете ожидание в блокировку.
Смотрите на типичные риски по изоляции:
— READ UNCOMMITTED: быстрый, но может читать мусор; годится только там, где ошибка не страшна.
— READ COMMITTED: обычно рабочая база для OLTP, но допускает неповторяемые чтения.
— REPEATABLE READ / SNAPSHOT: меньше аномалий, но возможны конфликты записи и рост версионного хранилища.
— SERIALIZABLE: максимум порядка, минимум параллелизма; применяйте точечно, иначе получите очередь вместо производительности.
Золотое правило: сначала мониторинг, потом индексы. Смотрите длительность транзакций, wait events, блокировки, deadlock graph и фактические планы. Если один запрос в транзакции ходит по таблице без нужного индекса, уровень изоляции уже вторичен — вы лечите симптом, а не причину.
Держите транзакции короткими, предсказуемыми и с четким порядком доступа к таблицам. Тогда изоляция будет инструментом, а не источником пятничных дедлоков.
Оптимизация производительности баз
@database_performance_tuning_arb
Транзакции и изоляция: как не словить грязное чтение, блокировки и дедлоки
Этот пост опубликован в Telegram-канале Оптимизация производительности баз. Подписаться можно по ссылке: @database_performance_tuning_arb.