栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

深入MYSQL之事务篇(一)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

深入MYSQL之事务篇(一)

关于mysql的事务,大多数java开发都是非常熟悉的。但是近期面试了一批同学,发现很多同学对mysql事务的理解都是停留在spring的@Transactional上,问到为什么使用事务时往往会背书一样回答出ACID的一些概念。照本宣科其实并不是我想听到的答案,相信真正了解过,思考过mysql原理和设计思想的开发都应该有更深一步的体会。

那么,想要深入谈谈某件事情,那首先得回到“这件事情是做什么的,有什么用”这个方向上面。那在设计事务的初衷,它是用来做什么的呢?我个人觉得至少有以下几点作用,分别以具体的应用场景举例:

1.某个业务操作是不可分割的,要么全部失败,要么全部成功。如电子记账系统里面,A给了B100块钱,要么交易失败,A和B的余额都不变,要么交易成功A的余额-100同时B的余额+100

2.开发人员为了性能和效率,采用反范式设计,即允许少量的冗余,通过空间换时间的方法来缩短查询业务的响应时间。如:某个业务要对博文进行排序,排序规则为按照博主的用户等级倒序排列。根据3NF的范式设计规则,那么资源表是不应该存在博主相关的字段的。但是往往为了性能原因,要在博文对应的表中新增用户等级这个冗余字段,并在用户等级提升时做冗余更新。那么这种情况下的更新一样可能会遇到原子性或者一致性问题。同理的,有时候会遇到需要频繁计数的场景,由于innoDB下查询count(*)会遇到全索引扫描的问题,性能比较低,往往需要计数表或者计数缓存的方案,那么前者在更新是也会遇到原子性或者一致性问题。

3.隔离性问题,正在处理的事务我不想被其他事务感知到,以免影响正常的业务逻辑。比如我有一个入库操作,会进行大量的数据插入,我还有一个定时任务用来做统计,会统计入库相关的大量指标。那么如果我在某个商品时入库就进行统计,有可能只统计到一半插入的数据,另一半的操作还在写入就没办法统计到。这种情况下我肯定是希望我能统计到相同一个时间版本的数据,这就涉及到事务的隔离性问题了。

4.持久性问题,如我在写数据的时候,希望它像是合同一样,我在签字之前完全可以放弃提交(事务的回滚),但是我一旦签字,那么这东西的效用应该是持久的。

在这些需求上,mysql商用引擎InnoDB采用MVCC的设计,支持了ACID兼容的事务(Transaction)功能。所谓的mvcc,就是一份数据存在多份版本,数据库会在事务启动的时候启动一个快照,以数据库事务的唯一的,自增的id(即transaction id)作为标记创建该部分数据的快照。那么在某个事务中,通过比较历史事务的undo log和活跃事务的id数组,即可以判断某个视图的数据是否可见,从而实现事务的隔离能力。

此外,innoDB自己维护了一份redo log,与mysql另外的binlog形成二阶段提交,从而保证了事务的一致性和原子性能力。题外话,关于二阶段提交,这种设计思想其实是很普遍的,在很多东西的设计上都能看见影子,如硬盘的各种Raid模式是如何实现数据备份的恢复的,等等。

本篇先简单介绍了mysql对事务是如何支持的,下一篇会介绍在java应用层,是如何结合spring框架和jdbc驱动进行真正工程上的事务管理。

关于redo log,undo log,binlog有空会做进一步的补充,未完待续....

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/677592.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号