V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
anzu
V2EX  ›  Java

JPA 与 MyBatis 混用时的事务问题

  •  
  •   anzu · 2021-06-17 11:24:25 +08:00 · 1934 次点击
    这是一个创建于 1248 天前的主题,其中的信息可能已经有所发展或是发生改变。

    代码大概是这样的

    @Repository
    public interface GroupDao extends JpaRepository<Group, Integer> {
        // ...
    }
    
    @Transactional
    public void test(Integer userId, Integer groupId) {
        if (isJoin()) {
            groupDao.saveAndFlush(new Group(userId));
        } else {
            groupDao.deleteByUserIdAndGroupId(userId, groupId);
        }
        System.out.println(groupMapper.getUserCount(groupId));// mybatis
        System.out.println(groupDao.countByGroupId(groupId)); // jpa 
    }
    

    当 jpa 执行 saveAndFlush 时,两者输出正确。但 jpa 执行删除操作时,mybatis 输出错误,jpa 输出正确。 更诡异的是,如果调换最后两行 mybatis 和 jpa 的输出代码顺序,那么无论执行哪个操作,两者均输出正确。

    mysql 单数据源,理论上 spring 应该会自动管理两者的事务,为什么会出现这种结果?

    第 1 条附言  ·  2022-03-30 17:21:16 +08:00
    无聊翻到这个历史问题,虽然大概没人看,姑且记录一下。

    spring data jpa 基于 hibernate ,而 hibernate 有一级缓存。分 IF 情况讨论。

    1. 当 groupDao 执行 delete 的时候,实际并没有提交 sql 到数据库,而是被缓存起来,于是之后 mybatis 的 mapper 统计的是未删除的旧数据,输出错误统计。此情况下如果调换最后两行语句,由于 groupDao 执行 count 查询,hibernate 自动将之前缓存的 sql 提交到了数据库,以保证 Dao 查询正确,之后再执行 mapper 统计得到的即是正确数据。

    2. 当执行 groupDao.saveAndFlush ,由于有 flush ,所以之后的输出都是正确的。

    所以混用两者的时候,注意 flush dao 。
    6 条回复    2021-06-18 13:03:43 +08:00
    ylls
        1
    ylls  
       2021-06-17 17:46:47 +08:00
    mybatis 输出错误 错误日志是什么
    coala
        2
    coala  
       2021-06-17 17:47:47 +08:00
    啥错误...
    Macolor21
        3
    Macolor21  
       2021-06-17 22:13:49 +08:00 via iPhone
    应该是 mybatis 查的结果 count 是 jpa 删除还没执行的结果吧,所以相对于代码上的串行,是执行错误。这个类似错误编译器优化执行语句顺序?
    Senorsen
        4
    Senorsen  
       2021-06-17 22:13:55 +08:00
    deleteByUserIdAndGroupId 方法怎么写的,@Modifying 有没有加 auto flush 参数,有可能是没 flush ?

    总之不建议混用 JPA 和 mybatis 这两层吧。。
    myCupOfTea
        5
    myCupOfTea  
       2021-06-18 10:06:53 +08:00
    JPA 依赖的是 Hibernate 吧,这么混用不太好吧
    fewok
        6
    fewok  
       2021-06-18 13:03:43 +08:00
    把 JPA 删了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2033 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 00:45 · PVG 08:45 · LAX 16:45 · JFK 19:45
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.