【问题标题】:spring boot application: jpa query returning old dataspring boot 应用程序:jpa 查询返回旧数据
【发布时间】:2016-12-19 18:44:14
【问题描述】:

我们创建了一个使用 1.3.5 版本的 spring boot 项目。我们的应用程序与 Mysql 数据库交互。 我们创建了一组 jpa 存储库,我们在其中使用 findAll、findOne 和其他自定义查询方法。

我们正面临一个随机发生的问题。以下是重现它的步骤:

  1. 使用 spring-boot 应用程序在 db 上触发读取查询。

  2. 现在使用上面读取查询返回的记录的mysql-console手动更改Mysql中的数据。

  3. 再次使用应用程序触发相同的读取查询。

在第3步之后,我们应该已经收到了第2步的修改结果,但我们得到的是修改前的数据。

现在,如果我们再次使用应用程序触发读取查询,它会为我们提供正确的值。

此问题随机发生。我们没有在我们的应用程序中使用任何类型的缓存。

调试的时候发现jpa-repository代码实际上是在调用mysql,它也获取了最新的结果,但是当这个调用返回到我们的应用服务时,奇怪的是返回值有旧数据。

请帮助我们找出可能的原因。

JPA/数据源配置:

  • spring.datasource.driverClassName=com.mysql.jdbc.Driver
  • spring.datasource.url=jdbc:mysql://localhost:3306/dbname?autoReconnect=true
  • spring.datasource.username=root
  • spring.datasource.password=xxx
  • spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect
  • spring.datasource.max-wait=15000
  • spring.datasource.max-active=100
  • spring.datasource.max-idle=20
  • spring.datasource.test-on-borrow=true
  • spring.datasource.remove-abandoned=true
  • spring.datasource.remove-abandoned-timeout=300
  • spring.datasource.default-auto-commit=false
  • spring.datasource.validation-query=SELECT 1
  • spring.datasource.validation-interval=30000
  • hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
  • hibernate.show_sql=false
  • hibernate.hbm2ddl.auto=update

服务方式:

     @Override
    @Transactional
    public List<Event> getAllEvent() {
        return  eventRepository.findAll();
    }

JPARepository:

public interface EventRepository extends JpaRepository<Event, Long> {
    List<Event> findAll();
}

【问题讨论】:

  • 你在打电话给 COMMIT; 吗?向我们展示您的更新查询和数据源以及 JPA 配置
  • Hitham,我已经更新了相关的详细信息。更新查询只是改变一个 varchar 属性列的值。
  • 鉴于您正在更改 Hibernate 背后的值,陈旧的值是否来自其一级缓存?
  • @Andy,但是这两个事务是完全独立的,对应两个不同的线程。
  • 您是如何验证的? minimal, complete, verifiable example 会让人们更容易看到正在发生的事情。

标签: spring jpa spring-boot spring-data-jpa


【解决方案1】:

你可以使用:

@Autowired
private EntityManager entityManager;

然后在再次查询同一个实体之前:

 entityManager.clear();

然后调用查询

【讨论】:

    【解决方案2】:

    这可能是因为一些“脏读”。遇到类似的问题,尝试使用事务锁,尤其是“可重复读取”,这可能会避免这个问题。如果我错了,请纠正我。

    【讨论】:

      【解决方案3】:
      @Cacheable(false)
      

      示例:

      @Entity
      @Table(name="table_name")
      @Cacheable(false)
      public class EntityName {
          // ...
      }
      

      【讨论】:

      • 在我的情况下,我在控制器 @Cacheable(cacheNames = AppCacheManager.DEFAULT_CACHE) 上有注释需要找到缓存的替代方案
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-12-21
      • 1970-01-01
      • 2021-09-15
      • 1970-01-01
      • 2020-02-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多