【问题标题】:JSF2 + EJB3 + CRUD with an user control to commit or rollback?JSF2 + EJB3 + CRUD 与用户控制提交或回滚?
【发布时间】:2012-03-29 19:52:12
【问题描述】:

我正在开发一个基于 JSF2 和 Glassfish 3.1 的 Java EE 应用程序。应用程序必须在数据库表上提供 CRUD 操作。使用具有 incell 编辑行为的 primeface dataTable 显示数据库表数据。 我想让用户去

  • 修改、添加和删除表格中的元素和
  • 仅在用户确定他的更改时提交(按下命令按钮)
  • 当用户想要放弃他的更改时回滚

表有一个实体,一个无状态的 EJB 负责与 entityManager 的接口以访问数据库。

问题是每次我删除表中的一行时,事务都会被提交,而用户没有任何控制权。

如何实现这种对提交/回滚的用户控制?

【问题讨论】:

    标签: jpa jsf-2 transactions ejb crud


    【解决方案1】:

    用户操作频繁地反映在数据库中,活动导致不必要的数据库调用和流量增加。相反,您应该仅在用户最终确认后提交。

    应在对象的副本或克隆上进行更改并让用户对其进行操作。当用户想要保存更改时,您可以保存修改后的副本。如果要丢弃更改,则可以从原始对象恢复初始状态。

    对于您当前的方法:

    问题是每次我删除表格中的一行时, 事务在没有任何控制权的情况下提交给用户。

    因为默认的flush模式是FlushModeType.AUTO,所以可以改成FlushModeType.COMMIT

    如何实现这种对提交/回滚的用户控制?

    通过使用UserTransaction 接口的bean 管理事务,您可以控制事务开始、提交、回滚等。


    编辑:根据 JSR-317,托管实体可能立即或稍后被持久化到数据库中特定于实现

    如果事务处于活动状态,则该事务的合规实现 规范允许立即写入数据库(即, 每当更新、创建和/或删除受管实体时), 然而,一个实现的配置需要这样 非延迟数据库写入不在此范围内 规范。

    【讨论】:

      【解决方案2】:

      问题是每次我删除表中的一行时,事务都会被提交,而用户没有任何控制权。

      这听起来很奇怪。如果您正在编辑数据表中的数据并回发这些编辑(通过 AJAX 或直接)并且数据源自无状态 bean,那么除了您正在处理分离的实体之外,它不能是任何其他东西。

      对这些实体或包含它们的列表的更改不会自动反映在数据库中。在这种情况下,没有自动提交事务的概念。我强烈不同意上面 Nayan 给出的答案。是的,用户事务让您可以控制提交,但这似乎根本不是您的问题。

      虽然您可能应该显示一些代码,但我的猜测是您只是在用户的每次删除操作之后在 EJB 服务上调用某种删除方法,然后期望相同的事务和持久性上下文仍然存在.但是在无状态 bean 中,一旦您退出最初为您提供实体的方法,这些就会消失。

      您最好的策略是让用户操作仅对@ViewScoped 支持 bean 缓存的数据进行操作。然后当且仅当用户确认更新操作时,您一次调用您的 EJB 服务并包含所有更改的项目。如果有一个父实体引用了包含您删除的所有项目的列表,您只需传递此父实体并确保在关系上设置了级联删除。

      也就是说,您似乎认为自己已经获得的模式得到了支持。此模式涉及使用@Stateful 会话bean 和extended persistence context。在这种情况下,会话 bean 的持久性上下文将缓存您的所有更改,直到您再次将其与事务关联。如果您在会话 bean 的非事务性方法中执行删除操作,并使用 @RemoveentityManager.clear() 将取消方法实现为非事务性方法,并将保存方法作为事务性 @Remove 方法(不需要在它的身体里做任何事情)然后你就会得到这个效果。

      除非您牢牢掌握 EJB 和事务,否则最好采用第一种策略。

      【讨论】:

      • 我已在答案中添加了更多信息,请参阅编辑部分,如果不是这样,请告诉我。
      • @NayanWadekar 您引用的文本是在事务方法期间保存实体时发生的情况。我的观点是,在用户确认之前,OP 根本不应该调用这个事务方法。
      • 谢谢,你是对的:当用户点击删除按钮时,会调用 ejb 方法 remove (em.remove(em.merge(entity));)。 “编辑”按钮(但仅使用 em.merge)也是如此,我错误地认为此操作应该由用户稍后提交,按下正确的按钮。
      • @ArjanTijms 如果用户使用 CMT 在托管实体上进行操作,那么更改将通过容器隐式反映在数据库中,有什么不同意的地方。
      • @NayanWadekar 本身是正确的,但在用户确认您不应该使用 CMT 对托管实体进行操作之前;)换句话说,对 JSF 托管 bean 内的分离实体进行操作。只有在用户确认后,才能使用其默认 CMT 调用 EJB 服务。因此,不要在用户每次删除操作后调用 ejb 的 remove 方法。
      猜你喜欢
      • 2023-04-11
      • 2011-01-22
      • 2020-03-11
      • 2019-05-07
      • 1970-01-01
      • 2013-05-15
      • 1970-01-01
      • 1970-01-01
      • 2015-06-14
      相关资源
      最近更新 更多