Прежде всего, поскольку Spring сам по себе не выполняет сохранение, он не может указать, что именно должно означать readOnly
. Этот атрибут является только подсказкой для провайдера, поведение в данном случае зависит от Hibernate.
Если вы укажете readOnly
как true
, режим сброса будет установлен как FlushMode.NEVER
в текущем сеансе Hibernate, чтобы сеанс не завершал транзакцию.
Кроме того, setReadOnly (true) будет вызываться при соединении JDBC, что также является подсказкой для базовой базы данных. Если ваша база данных поддерживает это (скорее всего, так и есть), это в основном имеет тот же эффект, что и FlushMode.NEVER
, но оно сильнее, поскольку вы даже не можете выполнить сброс вручную.
Теперь посмотрим, как работает распространение транзакций.
Если вы явно не установите readOnly
на true
, у вас будут транзакции чтения / записи. В зависимости от атрибутов транзакции (например, REQUIRES_NEW
) иногда ваша транзакция в какой-то момент приостанавливается, запускается новая и в конечном итоге фиксируется, а после этого первая транзакция возобновляется.
Хорошо, мы почти у цели. Давайте посмотрим, что приводит readOnly
в этот сценарий.
Если метод в транзакции read / write вызывает метод, требующий транзакции readOnly , первая должна быть приостановлена, так как в противном случае сброс / фиксация произойдет в конец второго метода.
И наоборот, если вы вызываете метод из транзакции readOnly , которая требует чтение / запись , снова первая будет приостановлена, поскольку она не может быть очищена / зафиксирована, и второй метод нуждается в этом.
В случаях readOnly-to-readOnly и read / write-to-read / write внешняя транзакция не должна быть приостановлена (если не указано распространение в противном случае, очевидно).