更新数据库时我应该更喜欢什么?什么是专业人士和两种方法都有用,何时使用其中一种?
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();
}
答案 0 :(得分:43)
在您的第一个示例中,数据更改在遇到flush后反映在数据库中,但仍处于事务中。
但在第二个例子中,您是立即提交交易。因此,对数据库和数据库进行了更改。交易也在那里结束。
有时,刷新可能有助于在正在进行的交易和数据之间保留数据。然后最后提交更改。因此,如果之后出现问题,您也可以回滚以前的更改,例如批量插入/更新。
答案 1 :(得分:14)
你确实读过了刷新和提交的javadoc,并且知道flush只是用于在事务中?它刷新(但不提交),而commit提交数据(显然)。他们是独特的;没有"偏好"要有。第一个例子是错误的,并且应该在调用flush(TransactionRequiredException)
时导致异常答案 2 :(得分:3)
两个代码示例都不会保留或合并要写入DB的实体状态。
我认为比较EntityManager.flush()
和EnityManager.EntityTransaction.commit()
不合适。
flush()必须包含在事务上下文中,除非需要(在极少数情况下),当EntityTransaction.commit()为您执行此操作时,您不必显式执行此操作。
请参阅此链接Is it necessary to call a flush() (JPA interface) in this situation?
请参阅此链接Question about flushing with JPA before a query is called以了解使用flush()
的方案答案 3 :(得分:0)
我会尽可能地进行容器管理的交易。由于Exception的可能性,Bean管理的事务通常需要更多的代码。此外,它更容易出错(回滚,资源管理)。
那就是说,我会在容器管理模式下提交后使用flush。这样我可以在我的存储模块中捕获可能的PersistenceExceptions,并将其转换为我的用例模块的一些更有意义的Exception。这是因为我不想在这里处理特定于存储的异常,因为我可能会将存储模块换成不使用JPA的东西......这从来没有发生在我身上:)
答案 4 :(得分:0)
我认为缺少的部分是,flush()只是添加到数据源以准备提交,提供实际ID但默认情况下不会保留。
因此,如果您需要flush()作为commit()工作,则需要通过以下方式将刷新模式设置为EntityManager中的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
我希望这个帮助