休眠事务回滚是否会删除“session.flush()”ed 实体?
我一直对.下面是伪代码示例:transaction.rollback
transaction = session.beginTransaction()
EntityA a = new EntityA();
session.save(a);
session.flush();
transaction.rollback();
当此代码正常工作时会发生什么情况?我是否在数据库中有实体?
我一直对.下面是伪代码示例:transaction.rollback
transaction = session.beginTransaction()
EntityA a = new EntityA();
session.save(a);
session.flush();
transaction.rollback();
当此代码正常工作时会发生什么情况?我是否在数据库中有实体?
简短的回答:不,数据库中不会有实体。
更长的答案:休眠足够聪明,不会向数据库发送插入/更新,直到它知道事务是否将被提交或回滚(尽管可以通过设置不同的 FlushMode 来更改此行为),在你的情况下,通过调用 flush,你正在强制将 SQL 发送到数据库,但你仍然有数据库事务来保护你, 当您调用回滚时,数据库事务将被回滚,删除在自身内部执行的更改,因此实际上不会保存任何内容。请注意,根据您配置的事务隔离级别,其他事务可能能够以某种方式看到您在保存和回滚之间短暂保存的 EntityA。另请注意,当您尝试从 DB 读取时,会自动调用 flush,在 99% 的情况下,不需要显式调用它。想到的一个例外是使用自动回滚测试进行单元测试时。
当您调用Hibernate时,基本上会记住会话中的某个位置,必须保存此对象。它可以决定他是否要立即发布,稍后或提交。这是一项性能改进,允许 Hibernate 在事务回滚时进行批处理插入或避免插入。session.save(a)
INSERT INTO...
当您调用 时,将强制对数据库发出休眠。实体存储在数据库中,但尚未提交。根据事务隔离级别,其他正在运行的事务不会看到它。但现在数据库知道了记录。session.flush()
INSERT INTO...
调用 时,休眠将回滚数据库事务。数据库处理回滚,从而删除新创建的对象。transaction.rollback()
现在考虑没有 的方案。首先,您从不接触数据库,因此性能更好,回滚基本上是无操作的。另一方面,如果事务隔离级别为 ,则其他事务甚至可以在提交/回滚之前看到插入的记录。没有这一点就不会发生,除非Hibernate没有决定隐式。flush()
READ UNCOMMITTED
flush()
flush()