readOnly и маршрутизация на реплику
Вопрос
Чтобы отправлять @Transactional(readOnly = true) на реплику, сделали AbstractRoutingDataSource, который смотрит TransactionSynchronizationManager.isCurrentTransactionReadOnly(). Запросы всё равно идут на мастер. Типичная причина?
Попробуйте сами
Выберите вариант, и откроется разбор.
Показать ответ и разбор
Коротко
Варианты ответа
- Флаг readOnly вообще не передаётся в TransactionSynchronizationManager
- Соединение берётся до флага readOnly; нужен
LazyConnectionDataSourceProxyправильный ответ - Реплика не поддерживает JDBC-соединения в режиме только для чтения
- AbstractRoutingDataSource работает только с JdbcTemplate, а не с JPA
Разбор
JpaTransactionManager получает соединение в начале транзакции, а признак readOnly в синхронизации выставляется позже, поэтому маршрутизатор видит «не только чтение». Обёртка LazyConnectionDataSourceProxy откладывает реальное получение соединения до первого запроса, когда флаг уже известен. Флаг в синхронизацию передаётся, а с JPA AbstractRoutingDataSource работает.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.