it-roy-ru.com

Почему "hibernate.connection.autocommit = true" не рекомендуется в Hibernate?

В Hibernate API есть свойство hibernate.connection.autocommit , которое можно установить в значение true. 

Но в API они упомянули, что не рекомендуется устанавливать его так:

Включает автокоммит для подключений JDBC в пуле (не рекомендуется Рекомендуется).

Почему это не рекомендуется? Каковы отрицательные последствия установки этого свойства в true?

19
Ponmudi VN

По умолчанию значение autocommit равно false, поэтому транзакция должна быть зафиксирована явно. Это может быть причиной того, что изменения не отражаются в базе данных, иначе можно попробовать сбросить, чтобы принудительно внести изменения перед фиксацией.

Когда вы закрываете сеанс, он неявно фиксируется в базе данных [зависит от реализации].

Если у вас есть каскадные транзакции, и вам необходимо выполнить откат для атомарности, вам необходимо контролировать транзакции, и в этом случае autocommit должен иметь значение false.

Либо установите autocommit как true, либо обрабатывайте транзакции явно.

Здесь хорошее объяснение этого.

Hibernate форум связано с этим.

Stackoverflow вопрос на нем.

13
user3145373 ツ

Насколько я понимаю, если Hibernate автоматически фиксирует ошибку, то сбой, который не пройден частично, не будет отменен. У вас будет неполный/сломанный граф объектов.

Если вы хотите, чтобы соединение с автоматическим подтверждением чего-либо было включено, вы всегда можете развернуть вновь созданную переменную Session, чтобы получить базовое соединение JDBC, setAutocommit(true) на нем, выполнить свою работу через API-интерфейсы JDBC, setAutocommit(false) и закрыть сеанс. Я бы не рекомендовал сделать это на Session, который уже сделал что-нибудь.

6
Craig Ringer

Все операторы базы данных выполняются в контексте физической транзакции, даже если мы явно не объявляем границы транзакции (BEGIN/COMMIT/ROLLBACK).

Если вы не объявляете границы транзакции, то каждый оператор должен быть выполнен в отдельной транзакции. Это может даже привести к открытию и закрытию одного соединения на оператор.

Объявление сервиса как @Transactional даст вам одно соединение на всю длительность транзакции, и все операторы будут использовать это одно изолированное соединение. Это намного лучше, чем вообще не использовать явные транзакции. В больших приложениях у вас может быть много одновременных запросов и снижение частоты запросов на соединение с базой данных определенно улучшает общую производительность приложения.

Так что эмпирическое правило таково:

  1. Если у вас есть транзакции только для чтения, которые выполняют только один запрос, вы можете включить автоматическую фиксацию для них.

  2. Если у вас есть транзакции, содержащие более одного оператора, вам нужно отключить автоматическую фиксацию, поскольку вы хотите, чтобы все операции выполнялись в одной единице работы, и вы не хотите оказывать дополнительное давление на ваш пул соединений.

5
Vlad Mihalcea

Не используйте антипаттерн сеанса для каждой операции: не открывайте и не закрывайте сеанс для каждого простого вызова базы данных в одном потоке. То же самое верно для транзакций базы данных. Вызовы базы данных в приложении выполняются с использованием запланированной последовательности; они сгруппированы в атомные единицы работы. Это также означает, что автоматическая фиксация после каждого отдельного оператора SQL в приложении бесполезна, поскольку этот режим предназначен для специальной консольной работы SQL. Hibernate отключает или ожидает, что сервер приложений немедленно отключит режим автоматической фиксации. Транзакции с базой данных никогда не являются обязательными. Все взаимодействие с базой данных должно происходить внутри транзакции. Следует избегать поведения автоматической фиксации для чтения данных, так как многие небольшие транзакции вряд ли будут работать лучше, чем одна четко определенная единица работы. Последний также более удобен в обслуживании и расширяем.

найти больше информации по этой теме

2
newday