当前位置: 首页 > article >正文

MyBatis 二级缓存脏读真实原因

很多同学熟悉 MyBatis 一级缓存、二级缓存基础用法但多表联查、跨Mapper更新场景下的缓存脏读漏洞90%的人都会踩坑。本文结合完整实战案例用大白话拆解脏读如何产生、一级缓存二级缓存双重隐患、Namespace隔离缺陷最后给出官方解决方案与企业级最佳实践可直接面试背诵、项目避坑。一、业务场景前置说明1. 业务数据表设计本次案例涉及两张关联表模拟日常一对多/关联业务场景表名业务作用初始测试数据dept部门基础信息表部门名ali、地址hzdeptNum部门人数统计表部门名ali、员工人数10502. Mapper 与 Namespace 隔离规则MyBatis 二级缓存核心特性以 Mapper 命名空间 Namespace 为单位独立隔离不同 Mapper 缓存相互独立、互不干扰。- DeptDao.xml负责多表关联查询同时查询部门信息部门人数- DeptNumDao.xml负责单表更新仅修改部门人数字段核心关键联查SQL 在 DeptDao 命名空间更新SQL 在 DeptNumDao 命名空间两个Mapper 属于不同Namespace。关联查询 SQLDeptDaoselect d.deptno,d.dname,d.loc,dn.numfrom dept d, deptNum dnwhere dn.name d.dname and d.dname #{name}人数更新 SQLDeptNumDaoupdate deptNum set num #{num} where name #{dname}二、官方必考MyBatis 完整缓存查询顺序标准答案这是 MyBatis 官方规定的固定查询优先级死记硬背1.先查询二级缓存跨SqlSession、Mapper全局缓存2. 二级缓存未命中 →再查询一级缓存当前SqlSession本地缓存3. 一级缓存也未命中 →最终查询数据库关键规则一级缓存的数据必须执行 commit / close / flush 操作才会同步到二级缓存中不执行这三个操作二级缓存永远是空的三、完整业务执行流程步骤1第一次查询数据仅存入一级缓存// 开启第一个SqlSessionSqlSession sqlSession factory.openSession();DeptDao deptDao sqlSession.getMapper(DeptDao.class);// 关联查询部门人数数据DeptVo deptVo deptDao.selectByDeptVo(ali);System.out.println(deptVo deptVo);执行流程1. 首次查询二级缓存为空→ 未命中2. 查询一级缓存→ 为空 → 未命中3. 访问数据库查询结果ali部门人数 10504. 数据仅存入当前SqlSession一级缓存5.致命重点该SqlSession 全程没有关闭、没有commit提交、没有flush刷新→一级缓存数据永远无法同步到二级缓存✅ 一级缓存存有旧数据❌ 二级缓存完全为空步骤2跨Mapper更新数据库数据// 开启全新第二个SqlSessionSqlSession sqlSession2 factory.openSession();DeptNumDao deptDao2 sqlSession2.getMapper(DeptNumDao.class);// 修改ali部门人数为 1000deptDao2.updateDeptVoNum(new DeptVo(ali,1000));// 提交事务数据库数据已真实修改sqlSession2.commit();// 关闭当前会话sqlSession2.close();执行流程1. 执行更新语句数据库deptNum人数永久修改为 10002. 更新操作归属DeptNumDao命名空间3. MyBatis 只会清空当前Namespace二级缓存4. 完全不会清理DeptDao的缓存数据。步骤3二次查询产生脏读// 复用【第一个未关闭的SqlSession】再次查询deptVo deptDao.selectByDeptVo(ali);System.out.println(deptVo deptVo);现象数据库人数已经是 1000但代码查询结果依旧是1050。明明数据已经更新却查不到最新结果这就是典型的缓存脏读。四、深度剖析脏读产生两大核心原因原因1二级缓存为空 命中一级缓存最直接、最核心原因结合官方缓存查询顺序完整闭环解释1. 二次查询先走二级缓存→ 因为没commit/close二级缓存一直是空的→ 未命中2. 按照顺序继续走一级缓存→ 缓存里有旧数据1050→命中3. 直接返回一级缓存的旧数据不会查询数据库4. 日志中Cache Hit Ratio: 0.0证明二级缓存命中率0本身就无数据简单总结没提交、没关闭 → 数据进不了二级缓存 → 二级缓存空 → 查询走一级缓存 → 脏数据诞生原因2二级缓存 Namespace 隔离缺陷就算手动关闭第一个SqlSession把一级缓存刷入二级缓存脏读依旧存在1. 联查结果缓存存放在DeptDao二级缓存2. 更新操作只清空DeptNumDao二级缓存3. 跨Namespace 的更新无法触发其他Mapper缓存清空4. 多表联查场景下不同表操作分散在不同Mapper缓存完全无法联动。致命问题多表关联业务一旦增删改和查询不在同一个 NamespaceMyBatis原生二级缓存必然脏读。五、官方解决方案cache-ref 共享缓存1. 标签作用MyBatis 提供cache-ref标签用于多个Mapper共享同一个二级缓存。打破 Namespace 独立隔离限制让多个命名空间共用一块缓存区域。2. 使用方式在需要联动的 Mapper 中引入对方的缓存命名空间!-- 在 DeptDao.xml 中配置 --cache-ref namespacecom.mybatis.dao.DeptNumDao/含义DeptDao 放弃独立二级缓存直接共用 DeptNumDao 的缓存。3、解决原理1. 当DeptNumDao执行更新操作时会清空公共缓存2. 关联查询的 DeptDao 共用此缓存缓存同步失效3. 下次查询缓存不存在自动访问数据库读取最新数据4. 彻底解决跨 Mapper 更新导致的缓存不同步问题。六、方案优缺点 企业级选型1. cache-ref 方案优缺点✅ 优点- MyBatis 原生自带无需引入第三方组件- 配置简单少量代码即可解决跨命名空间脏读❌ 缺点- 只适用于简单关联业务- 项目模块复杂、多表错综复杂时缓存耦合严重难以维护- 依旧无法解决分布式环境下多服务缓存同步问题。2. 企业级主流最佳实践绝大多数互联网/企业项目直接禁用 MyBatis自带二级缓存1. 原生二级缓存基于本地内存分布式部署下多服务缓存不互通2. Namespace 隔离机制导致联查场景大量脏读3. 事务、缓存刷新机制复杂线上问题难排查统一替换方案使用 Redis / Redisson 实现分布式业务缓存- 手动控制缓存存入、过期、主动删除- 跨服务、跨模块数据统一缓存管理- 灵活性更高、数据一致性更强、线上问题更好排查。七、核心总结面试满分版1.MyBatis 缓存查询顺序官方标准答案二级缓存 → 一级缓存 → 数据库2.缓存同步规则一级缓存数据只有执行commit / close / flush才会写入二级缓存3.本次脏读根源SqlSession 未提交/关闭 → 数据只在一级缓存 → 二级缓存为空 → 查询命中一级缓存旧数据4.二级缓存缺陷基于Namespace隔离跨Mapper更新无法联动清空缓存5.临时解决方案使用cache-ref共享缓存打破命名空间隔离6.生产环境规范禁用 MyBatis 原生二级缓存统一使用 Redis 分布式缓存。

相关文章:

MyBatis 二级缓存脏读真实原因

很多同学熟悉 MyBatis 一级缓存、二级缓存基础用法,但多表联查、跨Mapper更新场景下的缓存脏读漏洞,90%的人都会踩坑。 本文结合完整实战案例,用大白话拆解:脏读如何产生、一级缓存二级缓存双重隐患、Namespace隔离缺陷&#xff0…...

别再只用tic/toc了!MATLAB性能调优,这5种计时方法你用对了吗?(附R2023b实测对比)

MATLAB性能调优:超越tic/toc的5种高精度计时方案实战指南 在数值计算和算法开发领域,0.1秒的误差可能导致完全不同的仿真结果。当我们处理大规模矩阵运算、复杂系统仿真或深度学习训练时,选择正确的计时工具就像外科医生选择手术刀——精度决…...

【Gemini赋能Google Meet实时字幕】:2024企业级会议无障碍升级的5大落地陷阱与避坑指南

更多请点击: https://intelliparadigm.com 第一章:Gemini赋能Google Meet实时字幕的技术演进与企业价值定位 Google Meet 的实时字幕能力已从早期基于传统语音识别(ASR)的静态模型,跃迁至由 Gemini 多模态大模型深度驱…...

告别轮询!用DSP28335 GPIO中断实现矩阵按键响应,效率提升实战指南

DSP28335 GPIO中断驱动矩阵按键:从轮询到事件驱动的实战重构 在嵌入式系统开发中,按键响应速度往往直接影响用户体验和系统实时性。传统轮询方式虽然实现简单,但在处理矩阵键盘时会导致CPU资源浪费和响应延迟。我曾在一个工业控制面板项目中&…...

三菱FX3U串口通讯无协议编程与RS指令实现Modbus协议

引言 在工业自动化系统中,PLC与上位机之间的通讯至关重要。Modbus RTU协议 作为一种广泛应用的通讯协议,通常用于不同设备之间的数据交换。 对于三菱 FX3U系列PLC 来说,虽然它没有直接内置完整的Modbus RTU从站功能(早期型号需通过…...

LSLib深度解析:掌握《神界原罪》与《博德之门3》MOD制作的专业工具链

LSLib深度解析:掌握《神界原罪》与《博德之门3》MOD制作的专业工具链 【免费下载链接】lslib Tools for manipulating Divinity Original Sin and Baldurs Gate 3 files 项目地址: https://gitcode.com/gh_mirrors/ls/lslib LSLib是一个专为《神界原罪》系列…...

如何为Unity游戏添加多语言支持:XUnity.AutoTranslator完整指南

如何为Unity游戏添加多语言支持:XUnity.AutoTranslator完整指南 【免费下载链接】XUnity.AutoTranslator 项目地址: https://gitcode.com/gh_mirrors/xu/XUnity.AutoTranslator 你是否曾经因为语言障碍而无法享受心爱的Unity游戏?是否想要为你的…...

实战指南:从零开始掌握Visual C++运行库一键修复的高效用法

实战指南:从零开始掌握Visual C运行库一键修复的高效用法 【免费下载链接】vcredist AIO Repack for latest Microsoft Visual C Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist Visual C运行库是Windows系统中至关重要的组…...

必知必会:大模型位置编码RoPE与ALiBi位置编码详解

AI-Compass 致力于构建最全面、最实用、最前沿的AI技术学习和实践生态,通过六大核心模块的系统化组织,为不同层次的学习者和开发者提供从完整学习路径。 github地址:AI-Compass👈:https://github.com/tingaicompass/AI-Compass gitee地址:AI-Compass👈:https://gitee…...

别再只用默认样式了!LVGL Chart图表控件的10个美化技巧与高级样式配置

LVGL Chart图表控件进阶:10个专业级视觉优化技巧 在嵌入式GUI开发中,数据可视化是提升用户体验的关键环节。LVGL作为轻量级图形库的佼佼者,其Chart组件虽然开箱即用,但默认样式往往难以满足专业产品的视觉要求。本文将深入解析10个…...

从ITF到DSPF:华大九天Empyrean RCExplorer在版图寄生分析中的实战解析

1. 初识华大九天Empyrean RCExplorer 第一次接触华大九天的RCExplorer工具时,我正为一个复杂的模拟电路版图发愁。当时遇到的问题是:在完成版图后仿真时,发现关键路径的时序总是不达标,反复修改版图布局却始终找不到症结所在。直到…...

Visual C++运行库一键修复指南:解决Windows程序启动问题的完整方案

Visual C运行库一键修复指南:解决Windows程序启动问题的完整方案 【免费下载链接】vcredist AIO Repack for latest Microsoft Visual C Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist 当你打开某个软件时突然遇到"缺…...

sndcpy音频转发工具:Android设备音频镜像的完整指南

sndcpy音频转发工具:Android设备音频镜像的完整指南 【免费下载链接】sndcpy Android audio forwarding PoC (scrcpy, but for audio) 项目地址: https://gitcode.com/gh_mirrors/sn/sndcpy 想要在电脑上实时收听Android设备的音频内容吗?sndcpy音…...

League-Toolkit:基于LCU API的英雄联盟客户端自动化工具深度解析

League-Toolkit:基于LCU API的英雄联盟客户端自动化工具深度解析 【免费下载链接】League-Toolkit An all-in-one toolkit for LeagueClient. Gathering power 🚀. 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit League-Toolkit是…...

Kotlin ViewModel

Kotlin ViewModel 全流程指南 ViewModel 的核心作用是以注重生命周期的方式存储和管理界面相关的数据。它最伟大的地方在于:当手机屏幕旋转(配置更改)导致 Activity 重建时,ViewModel 中的数据不会丢失。 大纲 添加依赖创建 View…...

蓝叠模拟器抓包难题?用Proxifier+ Fiddler搞定HTTPS请求(保姆级图文教程)

蓝叠模拟器HTTPS抓包实战:Proxifier与Fiddler深度配置指南 在移动应用开发与安全测试领域,抓包分析是必不可少的技能。然而当遇到蓝叠模拟器这类特殊环境时,许多开发者发现常规的代理设置方法完全失效——因为蓝叠根本没有提供网络配置界面。…...

算法21,搜索插入位置

一道经典的二分查找应用题,通常被称为“搜索插入位置”。笔记中的思路非常清晰,下面为你整理这道题的具体解法、代码实现以及需要注意的细节。1. 题目理解题目描述:给定一个排序数组和一个目标值,在数组中找到目标值,并…...

OpenClaw 汉化版 Windows 一键安装指南|零基础 5 分钟部署 告别命令行

前言 在本地部署 AI 智能体时,英文界面晦涩、命令行操作复杂、环境配置繁琐,是很多零基础用户的三大痛点。OpenClaw 汉化中文版专为国内用户优化,采用全中文图形化界面 免环境配置 一键部署设计,全程无任何命令行操作&#xff…...

告别OrthoFinder限制:用IQtree+Notung搞定跨物种基因家族树(附兰科NB-ARC实战)

突破OrthoFinder局限:基于IQtree与Notung的跨物种基因家族进化分析实战 当你在研究一个特定基因家族的进化历程时,OrthoFinder的默认聚类机制可能会成为一道难以逾越的障碍。想象一下这样的场景:你精心收集了四个兰科物种的NB-ARC结构域序列&…...

终极视频字幕提取指南:如何用本地OCR工具高效提取87种语言硬字幕

终极视频字幕提取指南:如何用本地OCR工具高效提取87种语言硬字幕 【免费下载链接】video-subtitle-extractor 视频硬字幕提取,生成srt文件。无需申请第三方API,本地实现文本识别。基于深度学习的视频字幕提取框架,包含字幕区域检测…...

Python 工程化最佳实践:从 “玩具代码“ 到 “生产级项目“ 的完整指南

Python 工程化最佳实践:从 “玩具代码” 到 “生产级项目” 的完整指南📌 适用人群:Python 开发者、数据科学家、后端工程师 ⏱ 阅读时间:约 15 分钟 | 📦 附:可直接复用的项目模板与 CI/CD 流水线&#x1…...

从仿真波形到板卡调试:一次搞定Xilinx UltraScale+ FPGA DDR4读写测试全流程

从仿真波形到板卡调试:Xilinx UltraScale FPGA DDR4读写测试全流程实战指南 在FPGA系统设计中,DDR4内存接口的稳定性和性能往往是决定整个系统成败的关键因素。对于使用Xilinx UltraScale系列FPGA的工程师而言,从仿真验证到板卡调试的全流程掌…...

Zotero Connector进阶指南:解锁知乎内容完整抓取与Snapshot模式精准切换

1. 为什么你的知乎内容总是只保存快照? 很多初次使用Zotero Connector抓取知乎内容的朋友都会遇到一个头疼的问题:明明想保存完整的文章内容,结果在Zotero里只能看到一个网页快照。这个问题其实和Zotero Connector的默认设置有关。Zotero Co…...

3大核心技术解密:LeagueAkari本地自动化工具架构设计与实战指南

3大核心技术解密:LeagueAkari本地自动化工具架构设计与实战指南 【免费下载链接】League-Toolkit An all-in-one toolkit for LeagueClient. Gathering power 🚀. 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit LeagueAkari是一款…...

Vivado 2023.1 与 Questasim 2024.1 协同仿真环境搭建全攻略

1. 环境准备:安装与版本确认 在开始搭建Vivado 2023.1与QuestaSim 2024.1的协同仿真环境前,首先要确保两个软件都已正确安装。我最近在搭建这个环境时发现,新版本对系统环境的要求比旧版本更严格。建议使用Windows 10 64位专业版或企业版&…...

ZonyLrcToolsX:跨平台歌词下载解决方案与技术爱好者的音乐管理利器

ZonyLrcToolsX:跨平台歌词下载解决方案与技术爱好者的音乐管理利器 【免费下载链接】ZonyLrcToolsX ZonyLrcToolsX 是一个能够方便地下载歌词的小软件。 项目地址: https://gitcode.com/gh_mirrors/zo/ZonyLrcToolsX ZonyLrcToolsX 是一款功能强大的跨平台歌…...

Bebas Neue字体技术深度解析:开源无衬线显示字体的现代排版解决方案

Bebas Neue字体技术深度解析:开源无衬线显示字体的现代排版解决方案 【免费下载链接】Bebas-Neue Bebas Neue font 项目地址: https://gitcode.com/gh_mirrors/be/Bebas-Neue Bebas Neue作为一款采用SIL Open Font License 1.1许可证的开源显示字体&#xff…...

BIGEMAP自定义在线地图源:从零到一构建专属底图库

1. 为什么需要自定义地图源? 在日常工作中,我们经常会遇到这样的场景:项目需要特殊的地图底图,但软件内置的地图源无法满足需求;或者需要叠加多个地图源进行对比分析;又或者某些专业领域需要特定的地图数据…...

从信息学奥赛真题到项目实战:C++浮点数精度那些坑,你的double真的够用吗?

从信息学奥赛真题到项目实战:C浮点数精度那些坑,你的double真的够用吗? 在信息学奥赛的赛场上,一个看似简单的多项式计算题可能让许多选手栽跟头——不是算法思路不对,而是浮点数精度处理不当导致答案偏差。这种问题在…...

英雄联盟Akari助手:智能游戏伴侣让你的排位赛效率提升10倍

英雄联盟Akari助手:智能游戏伴侣让你的排位赛效率提升10倍 【免费下载链接】League-Toolkit An all-in-one toolkit for LeagueClient. Gathering power 🚀. 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit 还在为英雄联盟中繁琐的…...