Почему "hibernate.connection.autocommit = true" не рекомендуется в Hibernate?
В Hibernate API существует свойство hibernate.connection.autocommit, которое может быть установлено в true.
Но в API они упомянули, что не рекомендуется устанавливать его так:
Включает автообновление для объединенных соединений JDBC (это не рекомендуется).
Почему это не рекомендуется?
Каковы негативные последствия установки этого свойства в true?
Ответы
Ответ 1
По умолчанию значение autocommit равно false, поэтому транзакция должна выполняться явно. Это может быть причиной того, что изменения не отразятся в базе данных, иначе можно попытаться сбросить изменения до фиксации.
Когда вы закроете сеанс, он будет неявно зафиксирован в базе данных [зависит от реализации].
Когда у вас есть каскадные транзакции и требуется откат для атомарности, вам нужно иметь контроль над транзакциями, и в этом случае autocommit должен быть ложным.
Либо установите autocommit как true, либо обработайте транзакции явно.
Здесь является хорошим объяснением.
форум Hibernate, связанный с этим.
Вопрос о стекировании.
Ответ 2
Я понимаю, что если Hibernate autocommits, то флеш, который проваливается частично, не будет откатываться назад. У вас будет неполный/сломанный графический объект.
Если вы хотите установить соединение с autocommit для чего-то, вы всегда можете развернуть вновь созданный Session
, чтобы получить базовое соединение JDBC, setAutocommit(true)
на нем, выполнить свою работу через API JDBC, setAutocommit(false)
и закрыть сессия. Я бы не рекомендовал делать это на Session
, который уже сделал что-либо.
Ответ 3
Все операторы базы данных выполняются в контексте физической транзакции даже если мы явно не объявляем границы транзакций (BEGIN/COMMIT/ROLLBACK).
Если вы не объявляете границы транзакции, каждый оператор должен быть выполнен в отдельной транзакции. Это может даже привести к открытию и закрытию одного соединения для каждого заявления.
Объявление службы как @Transactional даст вам одно соединение для всей продолжительности транзакции, и все операторы будут использовать это одно изолированное соединение. Это лучше, чем использование явных транзакций в первую очередь. В больших приложениях у вас может быть много одновременных запросов, а снижение скорости запроса на соединение с базой данных, безусловно, улучшает общую производительность приложения.
Итак, эмпирическое правило:
-
Если у вас есть транзакции только для чтения, которые выполняют только один запрос, вы можете включить автоматическую фиксацию для них.
-
Если у вас есть транзакции, содержащие более одного оператора, вам необходимо отключить автоматическую фиксацию, так как вы хотите, чтобы все операции выполнялись в одном блоке работы, и вы не хотите оказывать дополнительное давление в вашем пуле соединений.
Ответ 4
Не используйте антипаттерн для сеанса за сеансом: не открывайте и не закрывайте сеанс для каждого простого вызова базы данных в одном потоке. То же самое верно для транзакций базы данных. Вызов базы данных в приложении производится с использованием запланированной последовательности; они сгруппированы в атомные единицы работы. Это также означает, что автоматическая фиксация после каждого отдельного оператора SQL бесполезна в приложении, так как этот режим предназначен для работы с SQL-консолью ad-hoc. Hibernate отключает или ожидает, что сервер приложений отключится, автоматически зафиксируйте режим. Операции с базой данных никогда не являются обязательными. Вся связь с базой данных должна происходить внутри транзакции. Следует избегать поведения в режиме автоматической фиксации данных для чтения, поскольку многие небольшие транзакции вряд ли будут работать лучше, чем одна четко определенная единица работы. Последняя также более удобна и расширяема.
найти дополнительную информацию по этому вопросу