在隔离机制中,InnoDB默认采用的Repeatable Read 和MVCC机制保证在事务内部尽量保证逻辑一致性。但如下的现象依然让人觉得不太合理。
1、复现
a) 表结构
CREATE TABLE `t` (
`a` int(11) NOT NULL DEFAULT ‘0′,
`b` int(11) DEFAULT NULL,
PRIMARY KEY (`a`)
) ENGINE=InnoDB DEFAULT CHARSET=gbk
表中2条记录
| 1 | 100 |
| 4 | 400 |
+—+——+
b) 操作过程:开两个session,操作序列如下
Session 1 |
Session 2 |
1)Begin |
|
2)Select * from t;
| 1 | 100 |
| 4 | 400 |
2 rows in set (0.01 sec)
|
|
|
3)Insert into t vlaues(2, 200); |
4)Select * from t;
| 1 | 100 |
| 4 | 400 |
2 rows in set (0.01 sec)
|
|
5)Update t set b = 200 where a = 2;
Query OK, 0 rows affected (0.01 sec)
Rows matched: 1 Changed: 0 Warnings: 0
|
|
6)Select * from t;
| 1 | 100 |
| 2 | 200 |
| 4 | 400 |
3 rows in set (0.01 sec)
|
|
从session 1整个过程看来,它试图更新一个不存在的记录(a=2),结果更新成功,并且之后这个记录可以访问。
2、分析
从其他正常的表象看来,在事务内,只要不涉及更新,事务外的任何更新都是不可见的。上面试验中session 1内update之前执行的select *得到的结果仍是2条记录。
虽然更新冲突时的策略见仁见智,但例子中的这个现象应该提供一种可以选择的方式(至少应该允许配置)。
接下来的篇幅主要分析出现这种现象的原因,以及通过简单修改实现如下的方式:对于查询不可见的记录,update操作不应该成功。
由于更新冲突策略的复杂性,本文不解决更多的问题,简单比如:insert操作由于主键冲突的原因,插入依旧不允许。
3、源码相关
先来说明一下为什么步骤4)中的查询结果仍为2条记录。
Innodb内部每个事务开始时,都会有一个事务id, 同时事务对象中还有一个read_view变量,用于控制该事务可见的记录范围(MVCC)。对于每个访问到的记录行,会根据read_view的trx_id(事务id)与行记录的trx_id比较,判断记录是否逻辑上可见。
Session 2中插入的记录不可见,原因即为session 1先于session 2,因此新插入的数据经过判断,不在可见范围内。对应的源码在row/row0sel.c [4040-4055].
{说明: 源码版本5.1.45, 下同}
发生的逻辑为
If(!lock_clust_rec_cons_read_sees(..)){
//检查该记录是否本事务可见
row_sel_build_prev_vers_for_mysql(….); //不可见则找上一个版本
if (old_vers == NULL) {goto next_rec;} //上一个版本没有这个记录,放弃
}
|
注意到表格中出现的Rows matched: 1。 这里是例子出现诡异的开始,也是根源。我们知道innoDB内部更新数据实际上是“先查后改”,跟这个Rows matched: 1结合起来,不难联想到,在执行update操作是,在“查”的阶段,事务能够访问到新插入的行。
猜测:问题出在,执行更新的时候,是否没有判断事务可见范围?
事实上确实如此,源代码上翻几行可以看到,在行数[3897-4017-4071]这个if-else逻辑。
if (prebuilt->select_lock_type != LOCK_NONE) {
//该操作需要加锁
}
else{
//{CODES A}
}
|
执行查询语句走的是else的逻辑,而控制版本可见范围的代码就在{CODES A}的位置中。
而当我们在session 1中执行update操作时,走的是if()的逻辑,这里,没有判断版本可见范围。
4、简单修改
既然是因为update的“查”过程没有检查版本可见范围造成,我们试着加上。
在row/row0sel.c[3907]行插入如下:
if(trx->read_view){
if (UNIV_LIKELY(srv_force_recovery < 5)
&& !lock_clust_rec_cons_read_sees(rec, clust_index, offsets, trx->read_view)) {
rec_t* old_vers;
err = row_sel_build_prev_vers_for_mysql(
trx->read_view, clust_index,
prebuilt, rec, &offsets, &heap,
&old_vers, &mtr);
if (err != DB_SUCCESS) {
goto lock_wait_or_error;
}
if (old_vers == NULL) {
goto next_rec;
}
}
}
|
新的执行结果为
Session 1 |
Session 2 |
1)Begin |
|
2)Select * from t;
| 1 | 100 |
| 4 | 400 |
2 rows in set (0.01 sec)
|
|
|
3)Insert into t vlaues(2, 200); |
4)Select * from t;
| 1 | 100 |
| 4 | 400 |
2 rows in set (0.01 sec)
|
|
5)Update t set b = 200 where a = 2;
Query OK, 0 rows affected (0.01 sec)
Rows matched: 0 Changed: 0 Warnings: 0
|
|
6)Select * from t;
| 1 | 100 |
| 4 | 400 |
2 rows in set (0.01 sec)
|
|
重申:这个修改仅仅从本文的例子出发,达到“事务内查询无法访问的记录,不能更新”这个目的, 其他更新冲突策略不在此范围内。 仅作交流使用 -_-
分享到:
相关推荐
2024-2030全球及中国控制膨胀合金箔行业研究及十五五规划分析报告
通信历年真题选择题汇总1.(DOC).doc
电子通信设计资料电子万年历设计与制作论文资料提取方式是百度网盘分享地址
前台框架基于Bootstrap这一HTML5响应式框架,能够自适应不同终端设备的屏幕大小,为用户提供良好的浏览体验。开发环境兼容myEclipse、Eclipse、Idea等多种工具,配合mysql数据库,实现数据的存储与管理。后台则采用SSM(SpringMVC + Spring + Mybatis)框架,保证系统的稳定与高效运行。 系统主要包括会员信息管理、员工信息管理、设备信息管理以及退出模块。会员信息管理模块详细记录了会员的基本信息、健身目标、消费记录以及健身习惯等,同时设有会员投诉管理模块,用于收集和处理会员的意见与建议。员工信息管理模块则涵盖了员工的基本信息、工资发放情况等,帮助俱乐部进行人事管理。设备信息管理模块则负责建立器械档案,跟踪维修情况,并合理安排器械摆放位置,以延长器械使用寿命。 数据库设计方面,会员表记录了会员的各项基本信息,包括姓名、性别、职业等;部门表与员工表则分别用于记录俱乐部的组织机构和员工信息;会员消费表记录了会员的消费详情;员工工资表则用于记录员工的工资发放情况;留言表用于收集会员的留言及回复;设备类别表与设备表则详细记录了会所内器械的分类与具
2024-2030全球及中国超级殷钢 32-5行业研究及十五五规划分析报告
行业分析报告
linux环境不能上网,用这个文件可以实现nginx免安装
“按点击量排序-基于内容的课程推荐网站的设计与实现(SSM+html)”是一个基于内容推荐概念的在线学习平台,旨在为用户提供个性化的课程推荐体验。系统的核心功能包括用户注册登录、课程浏览搜索、个性化推荐和热门课程按点击量排序展示。在技术架构方面,该系统采用SSM框架作为后端开发技术,包括Spring、Spring MVC和MyBatis,用于处理业务逻辑和数据持久化。前端界面则采用HTML设计实现,展示课程信息和用户交互界面。这样的技术选择不仅提供了稳定的后端支持,还保证了良好的前端用户体验。通过SSM框架以及HTML的结合,该课程推荐网站在功能性和性能方面表现优异。SSM框架提供了高效的业务处理和数据交互,HTML则赋予网站美观友好的用户界面,使用户能够轻松使用课程推荐功能。热门课程的点击量排序功能提高了用户浏览体验,使用户更快速地找到感兴趣的课程,从而提升整体用户满意度和学习效率。
行业分析报告
1:场景一主要有两个功能,第一个是控制左边图片,第二个是让右边文字逐一显示。 2:场景二功能简单一点,只控制左边人物出现,紧接着是文字显示。 3:场景三功能控制图片弹跳显示,我用for循环控制弹跳距离。 4:场景四控制图片从顶部往下滑落,停留1秒然后滑向右侧直至消失。 5:场景五慢慢显现,可点击进入婚礼。 6:场景六显现停留1.6秒,然后以碎片的形式向外散开。 7:场景七祝福贴纸随机排布,并且可拖动祝福贴纸。 8:添加祝福语中,需填写祝福语,否则不让提交。可提交的祝福语便随机散布在祝福墙中,可实现随意拖动功能,
AI论文体系建设是指建立一个完善的AI领域的论文研究框架和体系,以促进学术交流和知识积累。这一体系包括但不限于以下几个方面: 1. **研究主题界定**:明确AI领域的研究主题和范围,包括机器学习、深度学习、自然语言处理、计算机视觉等方向。 2. **文献综述**:对AI领域相关研究文献进行综述和分类,总结研究现状和发展趋势,为后续研究提供参考。 3. **研究方法论**:探讨AI研究的方法论,包括实验设计、数据采集、模型构建等方面的方法和技巧。 4. **实验验证**:强调实验验证在AI研究中的重要性,提倡开放数据和代码,以促进研究结果的可复现性和可验证性。 5. **学术交流**:倡导学术交流和合作,包括参加学术会议、发表论文、组织研讨会等方式,促进学术成果的传播和交流。 6. **学术评价**:建立科学的学术评价体系,包括SCI、EI等学术期刊和会议的评价标准,以及学术成果的评价指标和方法。 通过建设完善的AI论文体系,可以促进AI领域的学术研究和技术创新,推动人工智能技术的发展和应用。
行业分析报告
围绕着医疗安全与医疗机构管理精细化目标,借鉴HIMSS评级标准、JCI评审、等级医院评审标准规范,基于统一的技术平台架构下的医教研人财物六位一体的信息化管理解决方案,实现医疗卫生机构医务、护理、人力资源、科研、教学、医患关系、设备与物资供应链等日常管理运营信息化。 利用移动互联网技术构建专业的分享服务平台,以为会员提供相关知识、专家在线服务、法律咨询服务,并为医生、医疗机构和健康管理会所提供宣传服务等众多增值服务。 4 大目标: 高效诊疗、智慧医疗、精细管理、信息便民; 1 卡通: 一张诊疗卡。 1 个平台: 一个医院信息集成平台; 6 大应用: 医疗管理、临床信息、运营管理、移动物联、医疗协作、对外服务。
本项目是基于PHP的轻量级MVC框架设计源码,包含56个文件,其中主要包含50个php源代码文件。系统采用了PHP编程语言,实现了基于PHP7+的轻量级MVC框架。该框架适用于博客系统、新闻管理系统、企业官网和Api系统等多种应用场景,是这些系统的最佳选择。项目结构清晰,代码可读性强,易于理解和维护。
本Matlab程序的主要功能是实现飞行器的侧向和纵向的机动,通过设计横向和纵向的控制指令实现。系统状态(微分方程)的解算提供了两种方式,龙格库塔法和欧拉法。 主程序main_cexiang:实现飞行器的侧向机动; 主程序main_zongxiang:实现飞行器的纵向机动。
基于ssm+vue学生学籍管理系统源码数据库文档.zip
mybatis-plus-generato.jar 包,各个版本,免费下载。 mybatis-plus 代码生成器生成代码框架。各个版本,免费下载。 下载不了,关注我,评论区联系我。
springboot+vue“智慧食堂”设计与实现 系统主要包括首页,个人中心,用户管理,菜品分类管理,菜品信息管理,留言板管理,系统管理,订单管理等功能。 项目关键技术 开发工具:IDEA 、Eclipse 编程语言: Java 数据库: MySQL5.7+ 框架:ssm、Springboot 前端:Vue、ElementUI 关键技术:springboot、SSM、vue、MYSQL、MAVEN 数据库工具:Navicat、SQLyog
基于ssm+vue孩童收养信息管理系统源码数据库文档.zip
本文深入探讨了概率论在时尚产业中的应用,分析了如何利用统计学原理来预测和引导时尚潮流。内容涵盖了数据收集、市场趋势分析、消费者行为研究以及如何通过概率模型来优化设计和营销策略。文章适合时尚产业的设计师、市场分析师、品牌经理以及对时尚趋势感兴趣的学者和学生。无论是在设计新款服饰、制定市场推广计划,还是在学术研究中,本文都能提供有价值的见解和方法。 关键词 时尚产业