繁体   English   中英

具有扩展持久性上下文的有状态 EJB 以处理用户 session

[英]Stateful EJB with extended persistence context to handle user session

我正在使用 CDI session 范围 bean 来保存用户相关信息(他的用户实体 bean、凭据等)。 每次用户更改他的信息(如 email、密码等)时,我都有一个保存方法。 但是,我可以有一个具有扩展持久性上下文的有状态 session bean 来执行此操作。 如果我这样做,他的用户实体将在他的 session 期间被管理,并且对他的 email 等的更改将在不重新创建持久性上下文等的情况下同步。这是个好主意吗? 我应该有一个扩展的持久性上下文打开这么长时间吗? 这也会锁定用户对外部 bean 的更改,对吗? 如果我有管理员尝试更改此用户怎么办(可能发生)。

您需要注意一些副作用。

第一件事是你用来保存这个用户实体的扩展持久性上下文不应该用于其他太多,因为它会自动缓存所有被触摸的东西(L1 缓存)。

如果您需要在处理其他一些持久性上下文的其他操作中使用此连续附加的用户实体,则需要获取一个新实例,而不是使用 session scope 中的实例。

锁定的事情不会自动发生。 通常,不同的持久化上下文也可以修改同一个实体。 通常,最后一个进行任何写入的人将“获胜”。 如果要防止这种情况,可以利用 JPA 中的正常锁定操作。 对于这种情况,乐观锁可能最适合。

我很好奇这在实践中会有多好。 这肯定是一个新奇的想法。 通过阅读许多博客文章、文章、书籍和与许多开发人员的讨论,我感觉扩展的持久性上下文是鲜为人知的事情,并且没有为它创建太多的最佳实践。

有状态的 session bean 现在可以通过 CDI 作用域(因此在例如 HTTP session 被破坏时自动销毁)这一事实使整个概念更加可行。 但 CDI 也相对较新,很多人仍然需要探索如何最好地使用它。

我在各种 Java EE 6 项目中使用扩展的持久性上下文,这是场景:

  • 一个“外观”(sfsb),注入服务
  • 一个“服务”注入 EM
  • 一个“ dbproducer ”将 EM 生成到门面的会话 scope
  • 外观默认禁用所有事务(例如loadEntity()没有事务)
  • 某些外观方法显式启用事务(例如saveEntity()具有事务)

会发生什么:

  • 一个实体被加载并在整个对话期间保持管理(由持久性上下文完全缓存,在没有事务的情况下不会刷新)。
  • 如果(且仅当)保存实体时,将显式打开事务,并且如果事务成功,持久性上下文会刷新到数据库中。
  • 如果确实发生了任何其他编辑(例如由管理员),将抛出OptimisticLockingException ,并由应用程序处理

这就像一个魅力,感觉也很优雅:-)

一个警告 - 因为 EM 不可序列化 - *如果 *您在集群中工作,您将被迫使用粘性 session 策略,因为这些 EJB 无法从一台服务器移动到另一台服务器。

您可能还想考虑某种方式让 EM 加入现有事务(如果每个请求有多个服务调用,这很容易发生)。 如果您在非 Seam 3 堆栈上,则可以选择代理 EM,如果您在 Seam 3 上,请使用@Unwraps (Solder) 而不是@Produces并检查是否有要加入的事务。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM