spring-data-jpa-guide icon indicating copy to clipboard operation
spring-data-jpa-guide copied to clipboard

关于 AUTO 的 Flush 机制问题

Open herozzn opened this issue 2 years ago • 3 comments

老师,我看到您写的有两种情况会触发自动刷新:

  1. 事务 commit 之前,即指执⾏ transactionManager.commit() 之前都会触发
  2. 执⾏任何的 JPQL 或者 native SQL(代替直接操作 Entity 的⽅法)都会触发 flush

但是我在测试的时候,发现: 执行 count 查询的时候也会触发 AutoFlush 方法,请问这是为什么呢

    @Autowired
    private TransactionTemplate transactionTemplate;
    @Autowired
    private UserEntityRepository userEntityRepository;

    @Test
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    @Rollback(value = false)
    void testCountAutoFlush() {
        Long userCount = transactionTemplate.execute(transactionStatus -> {
            User user = userRepository.save(User.builder().name("test").email("[email protected]").build());
            long count = userRepository.count();
            user.setName("age");
            return count;
        });
    }

herozzn avatar Aug 23 '22 02:08 herozzn

是在 user.setName("age"),之前设置 sleep 发现的吗?你怎么看到 执行 count 查询的时候也会触发 AutoFlush 方法这个现象的?

zhangzhenhuajack avatar Aug 23 '22 03:08 zhangzhenhuajack

是在 org.hibernate.event.internal.DefaultAutoFlushEventListener#onAutoFlush 这个方法中打断点,在 count 的时候就会进到这个方法

然后日志的打印也是先执行 insert 再执行 count 再执行 update

Hibernate: insert into user (create_user_id, created_date, deleted, last_modified_date, last_modified_user_id, version, age, email, name, sex, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: select count(*) as col_0_0_ from user user0_
Hibernate: update user set create_user_id=?, created_date=?, deleted=?, last_modified_date=?, last_modified_user_id=?, version=?, age=?, email=?, name=?, sex=? where id=? and version=?

herozzn avatar Aug 23 '22 03:08 herozzn

从sql日志上,来看,你怎么确定的不是事务执行完(事务 commit 之前)执行的autoFlush,而是你执行了count语句之后执行的autoFlush ?

zhangzhenhuajack avatar Aug 23 '22 23:08 zhangzhenhuajack