我有一个网络应用程序。如果我不使用应用程序(命令行)对数据库进行更改,我的实体不会显示此更改。
有没有办法让实体知道数据已更改并且需要更新?
我有一个网络应用程序。如果我不使用应用程序(命令行)对数据库进行更改,我的实体不会显示此更改。
有没有办法让实体知道数据已更改并且需要更新?
您的问题是您正在使用资源本地事务类型。您有义务设计您的事务 begin() 和 commit() - 技术上称为事务分界。如果 EntityManager 保存时间过长,可能会导致数据过时——就像您的投诉一样——甚至会导致内存泄漏和性能下降。您必须制定自己的事务管理策略。
另一方面,您可以通过为 GlassFish 之类的应用程序服务器进行开发来避免头痛,将为通常由服务器注入的线程安全 EntityManager 创建一个 JTA 事务类型。因此,您可以保存所有交易管道。
我的论点引用了第 294 页引述后的 JSR-317 JPA 规范:
当容器管理的实体管理器在活动 JTA 事务的范围内被调用时,一个新的持久性上下文开始……持久性上下文被创建,然后与 JTA 事务相关联。当关联的 JTA 事务提交或回滚时,持久性上下文结束,并且由 EntityManager 管理的所有实体都变得分离。
有关在 GlassFish 中设置 JTA 事务类型的步骤,请参阅我在这篇文章中的回答。
如果您需要优先考虑在您的应用程序之外完成的数据库更新,而不是当前 EntityManager 中的更新(即 JTA 事务)操作。然后使用 EntityManager.refresh() 方法丢弃当前未完成的事务操作,直到 refresh() 调用并诉诸数据库最新状态。
虽然可能不是最优雅的解决方案,但您可以尝试调用refresh()
实体管理器。请参阅此答案:Java JPA - 同步数据库和实体
或者,您可以使用悲观锁来防止数据在使用实体时意外更改。
JPA 不是数据库观察者,底层的 JDBC 也不是。无法从数据库服务器通知您的某些实体包含旧的或不存在的数据。知道的唯一方法是刷新或尝试提交当前事务。