Entitymanager.flush()VS EntityManager.getTransaction()。commit - 我应该更喜欢什么?

时间:2012-06-15 09:38:19

标签: java jpa eclipselink

更新数据库时我应该更喜欢什么?什么是专业人士和两种方法都有用,何时使用其中一种?

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();
}

5 个答案:

答案 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

我希望这个帮助