Весна - транзакция только для чтения - PullRequest
23 голосов
/ 01 апреля 2010

Просто хотел получить ваши экспертные заключения по декларативному управлению транзакциями для Spring.Вот мои настройки:

  1. Уровень DAO - это простой старый JDBC с использованием Spring JdbcTemplate (без спящего режима и т. Д.)
  2. Сервисный уровень - это POJO с декларативными транзакциями следующим образом - save*, readonly = false, rollback for Throwable

С вышеприведенной настройкой все работает хорошо.Однако, когда я говорю get*, readonly = true, я вижу ошибки в моем файле журнала, говорящие Database connection cannot be marked as readonly.Это происходит для всех методов get * в слое обслуживания.

Теперь мои вопросы:

A.Нужно ли устанавливать get* только для чтения?Все мои get* методы являются чисто операциями чтения БД.Я не хочу запускать их в любом контексте транзакции.Насколько серьезна вышеуказанная ошибка?

B.Когда я удаляю конфигурацию get*, я не вижу ошибок.Более того, все мои простые операции get* выполняются без транзакций.Это путь?

C.Зачем кому-то хотеть иметь транзакционные методы, где readonly = true?Есть ли практическое значение этой конфигурации?

Спасибо!Как всегда, ваши отзывы очень ценятся!

Ответы [ 2 ]

23 голосов
/ 01 апреля 2010

В этом сообщении говорится, что поведение или флаг readOnly зависят от механизма сохранения.

C. Да, при использовании гибернации, это дает преимущества в производительности, устанавливая режим сброса на FLUSH_NEVER (как описано в связанном посте)

B. Да, вызовы JDBC не требуют транзакции (для hibernate требуется такая транзакция), поэтому удаление конфигурации @Transactional обрезает все управление транзакциями.

A. Я предполагаю, что spring вызывает connection.setReadOnly(true), но ваш драйвер JDBC не поддерживает это

Итог: не используйте readonly транзакции с простым JDBC.

И еще одна вещь - транзакции должны охватывать несколько запросов. Не делайте свои транзакции слишком мелкими. Сделайте их единицей работы .

5 голосов
/ 01 апреля 2010

A. Должен ли я сказать, получить * как только для чтения? Все мои методы get * являются чисто операциями чтения БД. Я не хочу запускать их в любом контексте транзакции. Насколько серьезна вышеуказанная ошибка?

На самом деле, вы, вероятно, все еще хотите запустить все свои get() в контексте транзакции, чтобы убедиться, что вы получаете согласованные чтения. Если, с другой стороны, вас это не волнует, вы можете соответственно установить уровень транзакции.

C. Зачем кому-то хотеть иметь транзакционные методы, где readonly = true? Есть ли практическое значение этой конфигурации?

  1. Для защиты от ошибочных записей в методах get () `
  2. В целях оптимизации. Как упоминал Божо, Hibernate может использовать эту информацию не только в некоторых базах данных, но и в драйверах JDBC.
...