如何维护EntityManager';JBoss下的Hibernate缓存是否处于一致状态?
我们正在使用Hibernate运行JBoss,并且遇到了这个问题 当会话bean使用EntityManager查找实体时,它可能已经存在于EntityManager的缓存中,并且其状态可能已经过时。如果代码使用这样的实体进行决策,它可能会做出错误的决策,从而产生bug 下面是一个例子 HTTP请求1。会话bean创建一个实体实例,并使用字段“A”将其存储为值1。持久化实体获取ID=4 HTTP请求2。会话bean查找ID=4的实体,将其字段“A”设置为值2并保存它 HTTP请求3。会话bean查找ID=4的实体并检查其字段“A”。如果值为1,它做一件事,如果值为2,它做另一件事 如果请求3中的EM恰好与请求1中的EM相同,则会发生意外行为。我对此进行了测试,得到了大约10%的失败案例 所以问题是——如何避免这种情况?每次调用em.refresh()或em.clear()以确保实体是最新的,这似乎是在浪费资源。Artem 这似乎是您的问题之一:-) 虽然我知道你以前得到的答案(包括我的答案)可能不是你所希望的,但它们不会改变:如何维护EntityManager';JBoss下的Hibernate缓存是否处于一致状态?,hibernate,caching,jboss,entitymanager,Hibernate,Caching,Jboss,Entitymanager,我们正在使用Hibernate运行JBoss,并且遇到了这个问题 当会话bean使用EntityManager查找实体时,它可能已经存在于EntityManager的缓存中,并且其状态可能已经过时。如果代码使用这样的实体进行决策,它可能会做出错误的决策,从而产生bug 下面是一个例子 HTTP请求1。会话bean创建一个实体实例,并使用字段“A”将其存储为值1。持久化实体获取ID=4 HTTP请求2。会话bean查找ID=4的实体,将其字段“A”设置为值2并保存它 HTTP请求3。会话bean查
- 实体管理器是映射到Hibernate会话的,通常需要是短期的。这篇文章很好地解释了与Hibernate会话相关的工作单元、事务和范围,如果您以前没有看过,请看一看李>
如果你的应用程序始终坚持实体管理者,你需要认真考虑改变这种策略;如果您只是在一些确实需要进行长事务的地方执行此操作,而不是使用
方法,那么肯定会有较小的缺点refresh()
- 与具有群集实现的不同,会话级缓存在不同的会话(实体管理器)之间不同步(按设计),对同一实体的并发更新通过Hibernate或应用程序级锁定进行处理
- 理论上,你可以(只要你的ORM访问被很好地分开)维护你自己的缓存(如果需要的话,集群化的)由不同的实体管理者持有的实体;您需要向每个服务器注册相应的服务器,以保持缓存同步。不过,我强烈建议不要使用这种方法,因为它不仅需要大量的实现,而且容易出现错误,而且这与Hibernate的范例背道而驰
- 实体管理器是映射到Hibernate会话的,通常需要是短期的。这篇文章很好地解释了与Hibernate会话相关的工作单元、事务和范围,如果您以前没有看过,请看一看李>
如果你的应用程序始终坚持实体管理者,你需要认真考虑改变这种策略;如果您只是在一些确实需要进行长事务的地方执行此操作,而不是使用
方法,那么肯定会有较小的缺点refresh()
- 与具有群集实现的不同,会话级缓存在不同的会话(实体管理器)之间不同步(按设计),对同一实体的并发更新通过Hibernate或应用程序级锁定进行处理
- 理论上,你可以(只要你的ORM访问被很好地分开)维护你自己的缓存(如果需要的话,集群化的)由不同的实体管理者持有的实体;您需要向每个服务器注册相应的服务器,以保持缓存同步。不过,我强烈建议不要使用这种方法,因为它不仅需要大量的实现,而且容易出现错误,而且这与Hibernate的范例背道而驰