【发布时间】:2019-08-12 05:41:26
【问题描述】:
我使用 JPA 和 Hibernate 开发了一个项目,我有两个线程:
- 线程 A:始终在读取并输出差异
- 线程 B:有一些写操作和一个在写完数据后提交的事务
如果我从/在数据库中删除数据或插入新数据,在从线程 B 提交事务后,在线程 A 中我会看到差异,即删除或添加了一些数据。 我的问题是当我更新现有数据时:提交后,线程 A 看不到差异,除非我没有在每次读取后清除 EntityManager。
这些是放在实体管理器上的属性:
EntityManager em = EMF.createEntityManager();
em.setProperty("hibernate.connection.autocommit", false);
em.setProperty("hibernate.connection.isolation", 2); // read committed
em.setProperty("javax.persistence.cache.storeMode", javax.persistence.CacheStoreMode.BYPASS);
em.setProperty("javax.persistence.cache.retrieveMode", javax.persistence.CacheRetrieveMode.BYPASS);
em.setProperty("hibernate.cache.use_query_cache", false);
em.setProperty("hibernate.cache.use_second_level_cache", false);
另一件事是我将记录器配置如下:
log4j.logger.org.hibernate=INFO, hb
log4j.logger.org.hibernate.SQL=DEBUG
log4j.logger.org.hibernate.type=TRACE
log4j.appender.hb=org.apache.log4j.ConsoleAppender
log4j.appender.hb.layout=org.apache.log4j.PatternLayout
向我展示所有 sql 和设置/返回的值。我观察到,在第一次读取时,它会从数据库中读取每一个值,然后在第二次读取时只读取 id 和新插入的值以防插入数据……但在更新时看起来并没有什么不同。
所以,考虑到我没有使用 Hibernate 的二级缓存,并且我绕过了会话缓存的存储和检索模式,更确切地说是因为我无法理解以及如何在不清除的情况下解决此问题每次读取后的持久化上下文?
谢谢。
【问题讨论】:
-
'除非我没有在每次读取后清除 EntityManager' 建议您始终为线程 A 打开一个持久性上下文。为什么不使用 per-unit-of-work 方法的持久性上下文呢?否则,一级缓存确实会导致结果过时(除非您明确地
clear上下文或在相关实体上调用refresh) -
我无法使用 per-unit-of-work 的持久性,因为当事务发生在分布式系统中时,我有自己的锁定表机制...
-
那么,我没有看到任何其他解决方法。据我所知,没有办法禁用一级缓存
标签: hibernate jpa caching sql-update dml