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

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

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

Включает автофиксацию для объединенных в пул соединений JDBC (не рекомендуется).

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


person Ponmudi VN    schedule 16.04.2014    source источник


Ответы (4)


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

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

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

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

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

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

person Vlad Mihalcea    schedule 30.01.2015

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

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

Когда у вас есть каскадные транзакции и вам нужно откатиться для атомарности, вам нужно иметь контроль над транзакциями, и в этом случае автофиксация должна быть ложной.

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

Вот хорошее объяснение этого.

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

вопрос о Stackoverflow.

person user3145373 ツ    schedule 16.04.2014

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

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

person Craig Ringer    schedule 16.04.2014
comment
hibernate использует JDBC под капотом. autoCommit — это концепция JDBCConnection, что означает транзакцию для каждого оператора. объем транзакцииn = 1 оператор sql [autocommit=true] hibernate.connection.autoCommit=true делает каждый оператор зафиксированным после его завершения, поэтому мы не можем зафиксировать/откатить 2 или более операторов как часть одной единицы работы. Мы хотим, чтобы выполнялись либо все операторы, либо ни один - для этого нам нужно отметить начало и конец транзакции и отключить автокоммит. - person Karan Kaw; 22.03.2017
comment
hibernate.connection.autocommit = false 2 Сценарии Граница явной транзакции: sessionFactory.openSession() session.beginTransaction() session.getTransaction().commit()//Очищает сеанс, фиксирует Txn session.close() Граница неявной транзакции sessionFactory.openSession () // Не видно использования транзакции, // но ее неявный txn, потому что - Autocommit имеет значение false session.flush() session.close() Здесь - Когда мы закрываем сеанс, Спецификация не ясна, поэтому поведение конкретного поставщика в Oracle - все sql операторы фиксируются в postgresql - все операторы sql откатываются - person Karan Kaw; 22.03.2017

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

дополнительная информация по этой теме

person newday    schedule 08.01.2017