Spring - Сделка Readonly
Просто хотелось, чтобы ваши экспертные мнения касались декларативного управления транзакциями для Spring. Вот моя настройка:
- Уровень DAO - это простой старый JDBC с использованием Spring JdbcTemplate (без спящего режима и т.д.)
- Уровень обслуживания - POJO с декларативными транзакциями следующим образом:
save*, readonly = false, rollback for Throwable
Все работает отлично с настройкой выше. Однако, когда я говорю get*, readonly = true
, я вижу ошибки в моем файле журнала, говоря Database connection cannot be marked as readonly
. Это происходит для всех методов get * в уровне обслуживания.
Теперь мои вопросы:
а. Должен ли я устанавливать get*
как только для чтения? Все мои методы get*
- это чистые операции чтения DB. Я не хочу запускать их в любом контексте транзакций. Насколько серьезной является вышеуказанная ошибка?
В. Когда я удаляю конфигурацию get*
, я не вижу ошибок. Более того, все мои простые операции get*
выполняются без транзакций. Это путь?
С. Почему кто-то хочет иметь транзакционные методы, где readonly = true
? Существует ли какое-либо практическое значение этой конфигурации?
Спасибо! Как всегда, ваши отзывы очень ценятся!
Ответы
Ответ 1
Этот пост говорит о том, что поведение или флаг readOnly
зависят от продолжительности процесса.
C. Да, при использовании спящего режима он дает преимущества производительности, устанавливая режим очистки на FLUSH_NEVER
(как описано в связанном сообщении)
B. Да, вызовы JDBC не требуют транзакции (для спящего режима требуется один), поэтому удаление конфигурации @Transactional
упрощает управление транзакциями.
A. Я бы предположил, что spring вызывает connection.setReadOnly(true)
, но ваш драйвер JDBC не поддерживает этот
Нижняя строка: не используйте транзакции readOnly
с простым JDBC.
И еще одно - транзакции должны охватывать несколько запросов. Не делайте транзакции слишком мелкозернистыми. Сделайте их единицей работы.
Ответ 2
а. Должен ли я сказать get * как только для чтения? Все мои методы get * - это чистые операции чтения DB. Я не хочу запускать их в любом контексте транзакций. Насколько серьезной является вышеуказанная ошибка?
На самом деле вы, вероятно, все же хотите запустить все свои get()
в контексте транзакции, чтобы убедиться, что вы получаете согласованные чтения. Если, с другой стороны, вас это не волнует, вы можете соответствующим образом установить уровень транзакции.
С. Почему кто-то хочет иметь транзакционные методы, где readonly = true? Существует ли какое-либо практическое значение этой конфигурации?
- Чтобы защитить от ошибочных записей в методах get() `
- Для целей оптимизации. Мало того, что Hibernate может использовать эту информацию, как отметил Божо, но некоторые базы данных/драйверы JDBC также могут использовать эту информацию.