Выбор ответа Senior Транзакции и @Transactional обновлено

readOnly и маршрутизация на реплику

Вопрос

Чтобы отправлять @Transactional(readOnly = true) на реплику, сделали AbstractRoutingDataSource, который смотрит TransactionSynchronizationManager.isCurrentTransactionReadOnly(). Запросы всё равно идут на мастер. Типичная причина?

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: Соединение берётся до флага readOnly; нужен LazyConnectionDataSourceProxy. JpaTransactionManager получает соединение в начале транзакции, а признак readOnly в синхронизации выставляется позже, поэтому маршрутизатор видит «не только чтение».

Варианты ответа

  1. Флаг readOnly вообще не передаётся в TransactionSynchronizationManager
  2. Соединение берётся до флага readOnly; нужен LazyConnectionDataSourceProxyправильный ответ
  3. Реплика не поддерживает JDBC-соединения в режиме только для чтения
  4. AbstractRoutingDataSource работает только с JdbcTemplate, а не с JPA

Разбор

JpaTransactionManager получает соединение в начале транзакции, а признак readOnly в синхронизации выставляется позже, поэтому маршрутизатор видит «не только чтение». Обёртка LazyConnectionDataSourceProxy откладывает реальное получение соединения до первого запроса, когда флаг уже известен. Флаг в синхронизацию передаётся, а с JPA AbstractRoutingDataSource работает.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.