繁体   English   中英

Hibernate事务回滚是否删除“session.flush()”ed实体?

[英]Does a Hibernate transaction rollback delete “session.flush()”ed entities?

我对transaction.rollback感到困惑。 这是示例伪代码:

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

这段代码有效时会发生什么? 我是否在数据库中拥有该实体?

简答:不,你不会在数据库中拥有实体。

更长的答案:hibernate足够智能,不会向DB发送插入/更新,直到它知道事务是否将被提交或回滚(虽然这种行为可以通过设置不同的FlushMode来改变),在你的情况下通过调用flush您强制将SQL发送到数据库,但仍然有数据库事务来保护您,当您调用回滚时,数据库事务将回滚,删除在其自身内执行的更改,因此实际上不会保存任何内容。 请注意,根据您配置的事务隔离级别,其他事务可能会以某种方式查看您在保存和回滚之间保存的EntityA。 另请注意,当您尝试从DB读取时会自动调用flush,在99%的情况下,不需要显式调用它。 我想到的一个例外是使用自动回滚测试进行单元测试时。

当你调用session.save(a) Hibernate基本上会记住会话中的某个地方必须保存这个对象。 它可以决定是否要立即,稍后或提交时发出INSERT INTO... 这是性能改进,允许Hibernate批量插入或在事务回滚时避免它们。

当你调用session.flush() ,Hibernate被迫对数据库发出INSERT INTO... 实体存储在数据库中,但尚未提交。 根据事务隔离级别,其他正在运行的事务将不会看到它。 但现在数据库知道了记录。

当您调用transaction.rollback() ,Hibernate回滚数据库事务。 数据库处理回滚,从而删除新创建的对象。

现在考虑没有flush()的场景。 首先,你永远不会触摸数据库,因此性能更好,回滚基本上是无操作。 另一方面,如果事务隔离级别为READ UNCOMMITTED ,则其他事务甚至可以在提交/回滚之前查看插入的记录。 如果没有flush()这将不会发生,除非Hibernate没有决定隐式地flush()

我认为你对flushcommit感到困惑。

flush()使状态与数据库同步,但它没有进行提交。 事务仍然可以看到状态,因此您可以调用rollback进行回滚。

所以你的问题的答案是:不,你没有数据库中的实体(a)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM