Транзакции Kafka и read_committed

Last Stable Offset, откатанные записи и почему транзакции без read_committed бессмысленны.

Транзакции в Kafka позволяют записать пачку сообщений (возможно, в разные партиции и топики) так, чтобы они стали видимы читателям одновременно — либо все, либо ни одного. Продюсер открывает транзакцию, пишет записи и завершает её commit или abort.

Ключевая деталь: транзакции работают только в паре. Записи откатанной транзакции физически остаются в логе — Kafka не умеет удалять уже записанное. Их отфильтровывает читатель, и только если он настроен на isolation.level=read_committed. При значении по умолчанию read_uncommitted консьюмер увидит и обработает откатанные записи. Это классическая ошибка: транзакции включили, изоляцию — нет.

В режиме read_committed появляется вторая граница чтения — Last Stable Offset (LSO). Это оффсет, ниже которого нет незавершённых транзакций. Такой консьюмер читает до LSO, а не до High Watermark, и пропускает записи откатанных транзакций.

Отсюда важное следствие для проектирования: открытая транзакция задерживает чтение всей партиции. Долгая транзакция в Kafka — это не «медленно потом», а «не видно сейчас». Транзакции стоит держать короткими, а transaction.timeout.ms — осмысленным.

И честная оговорка про exactly-once: транзакции дают его для схемы «читаем из Kafka, обрабатываем, пишем в Kafka», где коммит оффсетов входит в ту же транзакцию. Как только в цепочке появляется внешняя база или HTTP-вызов, гарантия заканчивается и нужен идемпотентный обработчик.

Разобрать это в симуляторе Интерактивный сценарий: настраиваешь кластер, ломаешь его и смотришь, что происходит

Частые вопросы

Сильно ли транзакции замедляют работу?

Накладные расходы заметны при коротких транзакциях: каждая добавляет служебные записи и координацию. Пачки разумного размера обычно приемлемы.

Что видит read_uncommitted-консьюмер?

Всё подряд до High Watermark, включая записи откатанных транзакций.

Даёт ли это exactly-once с внешней базой?

Нет. Для внешних систем нужен идемпотентный обработчик или паттерн outbox.

Дальше по теме

Что такое партиция в Kafka Consumer lag: что это и как с ним работать acks в Kafka: 0, 1 и all ISR и min.insync.replicas Ребалансировка consumer group