51

更新数据库时我应该更喜欢什么?两种方法的优缺点是什么?我什么时候应该使用其中一种?

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

5 回答 5

54

在您的第一个示例中,数据的更改在遇到刷新后反映在数据库中,但它仍在事务中。

但在第二个示例中,您将立即提交事务。因此,对数据库进行了更改,事务也到此结束。

有时,刷新可能有助于在正在进行的事务之间保留数据,然后最终提交更改。因此,如果之后出现问题,您也可以回滚之前的更改,例如批量插入/更新。

于 2012-06-15T10:17:45.227 回答
18

您确实阅读了有关刷新和提交的 javadoc,并且知道刷新仅用于事务中吗?它刷新(但不提交),而提交提交数据(显然)。它们是不同的;没有“偏好”。第一个例子是错误的,应该导致调用flush时出现异常(TransactionRequiredException)

于 2012-06-15T09:52:13.000 回答
4

您的两个代码示例都不会持久化或合并要写入数据库的实体状态。

我认为比较EntityManager.flush()和不合适EnityManager.EntityTransaction.commit()

flush() 必须包含在事务上下文中,除非需要(在极少数情况下),当 EntityTransaction.commit() 为您执行此操作时,您不必显式执行此操作。

请参阅此链接在这种情况下是否需要调用flush()(JPA 接口)?

请参阅此链接Question about flushing with JPA before a query is called for a scenario to use flush()

于 2012-06-15T09:58:49.580 回答
0

我会尽可能地进行容器管理事务。由于异常的可能性,Bean 管理的事务通常需要更多的代码。此外,它更容易出错(回滚、资源管理)。

也就是说,我会在容器管理模式下提交后使用刷新。这样我就可以在我的存储模块中捕获可能的 PersistenceExceptions 并将其转换为对我的用例模块更有意义的异常。这是因为我不想在这里处理特定于存储的异常,因为我可能会将存储模块换成不使用 JPA 的东西......这从未发生在我身上:)

于 2014-01-17T19:51:19.767 回答
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

我希望这有帮助

于 2015-06-22T08:29:16.337 回答