Подтвердить что ты не робот

Откат транзакции Hibernate удаляет объекты session.flush()?

Меня смутило transaction.rollback. Вот пример псевдокода:

transaction = session.beginTransaction()    
EntityA a = new EntityA();    
session.save(a);    
session.flush();    
transaction.rollback();

Что происходит, когда этот код работает? Есть ли у меня объект в базе данных или нет?

4b9b3361

Ответ 1

Короткий ответ: Нет, у вас не будет объекта в базе данных.

Более длинный ответ: hibernate достаточно умен, чтобы не отправлять вставки/обновления в БД, пока не узнает, будет ли транзакция выполнена или откат (хотя это поведение можно изменить, установив другой FlushMode), в вашем случае при вызове flush вы вынуждаете SQL быть отправленным в БД, но у вас все еще есть транзакция DB, чтобы защитить вас, когда вы вызываете rollback, транзакция DB будет отброшена, удалив изменения, выполненные внутри себя, и, следовательно, ничто не будет фактически сохранено. Обратите внимание, что в зависимости от настроенного уровня изоляции транзакций другие транзакции смогут каким-то образом увидеть EntityA, который вы сохранили за короткое время между сохранением и откатом. Также обратите внимание, что флеш вызывается автоматически при попытке прочитать из БД, в 99% случаев его явно не нужно. Единственное исключение, которое приходит на ум, - это тестирование устройства с автоматическим откатом.

Ответ 2

Когда вы вызываете session.save(a) Hibernate в основном помнит где-то внутри сеанса, что этот объект должен быть сохранен. Он может решить, хочет ли он немедленно выпустить INSERT INTO..., некоторое время спустя или совершить. Это улучшение производительности, позволяющее Hibernate вставлять вставки или избегать их, если транзакция отменяется.

Когда вы вызываете session.flush(), Hibernate вынужден выдать INSERT INTO... в базу данных. Сущность хранится в базе данных, но еще не совершена. В зависимости от уровня изоляции транзакции он не будет отображаться другими работающими транзакциями. Но теперь база данных знает о записи.

Когда вы вызываете transaction.rollback(), Hibernate свертывает транзакцию базы данных. База данных обрабатывает откат, удаляя только что созданный объект.

Теперь рассмотрим сценарий без flush(). Прежде всего, вы никогда не прикасаетесь к базе данных, чтобы производительность была лучше, а откат - это, в принципе, не-op. С другой стороны, если уровень изоляции транзакции READ UNCOMMITTED, другие транзакции могут видеть вставленную запись даже до фиксации/откат. Без flush() этого не произойдет, если Hibernate не решит flush() неявно.

Ответ 3

Я думаю, вы путаетесь с flush и commit.

flush() синхронизирует состояние с базой данных, но не выполняет фиксацию. Состояние все еще видно по транзакции, поэтому вы можете вызвать откат для отката.

Итак, ответ на ваш вопрос: no, у вас нет сущности (a) в базе данных.