Entitymanager.flush()VS EntityManager.getTransaction()。commit – 我应该select什么?
更新数据库时应该如何select? 两种方法的优缺点是什么?何时使用这两种方法?
public void disemployEmployee(Integer employeeId, Date endDate) { Employee employee = (Employee)em.find("Employee", employeeId); employee.getPeriod().setEndDate(endDate); em.flush(); } public void disemployEmployee(Integer employeeId, Date endDate) { Employee employee = (Employee)em.find("Employee", employeeId); em.getTransaction().begin(); employee.getPeriod().setEndDate(endDate); em.getTransaction().commit(); }
在你的第一个例子中,数据的改变在遇到flush之后反映在数据库中,但是它仍然在事务中。
但在第二个例子中,您正在立即提交事务。 因此,这些更改被制作成数据库,事务也在那里结束。
有时,刷新可能有助于将数据保存在正在进行的事务之间,然后最后再提交更改。 因此,如果之后出现一些问题,例如批量插入/更新,也可以回滚以前的更改。
你没有阅读javadoc的刷新和提交,并知道刷新只用于交易内? 它刷新(但不提交),而提交提交数据(显然)。 他们是独特的; 没有“偏好”。 第一个例子是错误的,并且会导致调用flush(TransactionRequiredException)
这两个代码示例都不会持久化或合并要写入数据库的实体状态。
我不认为比较适合比较EntityManager.flush()
和EnityManager.EntityTransaction.commit()
。
flush()必须被包含在一个事务上下文中,除非需要(在极less数情况下),EntityTransaction.commit()为你做这件事情时,你不需要明确地做。
请参阅此链接在这种情况下是否需要调用flush()(JPA接口)?
请参阅此链接关于在使用flush() 方法调用查询之前使用JPA刷新的问题
我会尽可能去容器pipe理的交易。 Beanpipe理的事务通常需要更多的代码,因为Exception的可能性。 另外,它更容易出错(回滚,资源pipe理)。
这就是说,我将在容器pipe理模式下提交后使用flush。 这样我可以捕获我的存储模块中可能的PersistenceExceptions,并将其转换为我的用例模块更有意义的exception。 这是因为我不想在这里处理特定于存储的exception,因为我可能会将存储模块换成不使用JPA的东西……这从来没有发生过我:)
我认为缺less的部分是,flush()只是添加到数据源准备提交,给出实际的ID,但默认情况下不持续。
所以,如果你需要flush()来作为commit(),你需要在EntityManager中通过以下方式将flush模式设置为Commit:
void setFlushMode(FlushModeType flushMode) Set the flush mode that applies to all objects contained in the persistence context.
请注意,FlushModeType是具有以下两个值的枚举:
FlushModeType AUTO(默认)在执行查询时进行刷新。 从以下版本开始:JPA 1.0 FlushModeType COMMIT刷新在事务提交时发生。 提供商可能会在其他时间刷新,但不是必需的。 从以下版本开始:JPA 1.0
我希望这个帮助