mybatis LocalCache踩坑记录

本文记录了一次因MyBatis一级缓存导致的线上问题,当根据非路由ID查找订单时,由于事务内两次查询使用了同一缓存,造成更新失效。分析了MyBatis缓存机制,并提出了三种解决方案:避免事务、设置flushCache为true、使用Statement级别查询。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    上周周三下午,准备去吃饭的时候,值班突然找过来说用户操作时爆出订单不存在的问题,因为之前做了分表连续很长一段时间都没问题,而且当时找过来的都是一些因为产品或者QA操作不当找不到记录的情况,就没有在意这些,当时以为几分钟就能搞定,但是没想到居然是线上日志爆出的问题,经过验证订单确实不存在!心想完了,晚饭没了,说不定地铁末班车也没了

背景

    聊这次问题之前向先交代一下背景,之前做了分表,分表逻辑很简单,靠着一笔订单中上游系统生成的订单的订单号A作为路由 id 去区分这笔订单究竟去入到哪张表里,但是一笔订单有很多订单号,如果我想根据我们传给下游系统的订单号B去查找记录该怎么办呢?于是针对这种场景我们做了一个映射表,专门维护A B间映射的表,详情如下图

插入的示意图如下所示

以路由id查找的方式如下图所示,跟插入类似

以非路由id去查找订单的示意图

其实我觉得蛮容易看懂的,无非多了一步映射

问题产生

    其实通过上述逻辑不难看出,对于非路由id非常依赖映射表,这次问题的产生也是因为映射表

    当我们查看这些单子的时候发现所有单子都是一种情况就是Order表有数据,映射表没数据,当时觉得很奇怪,因为其他业务先也用到了这块入表的逻辑但为什么其他业务没问题

    先来介绍一我们对于映射表和订单表的处理逻辑 

@Componet
public class OrderInfoProxy{
    
    @Resource
    private OrderDao orderDao;

    @Resource
    private OrderMappingDao orderMappingDao;

    @Transactional(rollback = Exception.class)
    public void updateOrder(Order order){
        Order dbOrder = orderDao.selectByIdA
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值