在码农的世界里,优美的应用体验,来源于程序员对细节的处理以及自我要求的境界,年轻人也是忙忙碌碌的码农中一员,每天、每周,都会留下一些脚印,就是这些创作的内容,有一种执着,就是不知为什么,如果你迷茫,不妨来瞅瞅码农的轨迹。
- 优美的音乐节奏带你浏览这个效果的编码过程
- 坚持每一天,是每个有理想青年的追求
- 追寻年轻人的脚步,也许你的答案就在这里
- 如果你迷茫 不妨来瞅瞅这里
事务就是要保证一组数据库操作,要么全部成功,要么全部失败。
在 MySQL 中,事务支持是在引擎层实现的,MySQL 原生的 MyISAM 引擎就不支持事务,所以就有了 InnoDB 引擎。
1 前言
当数据库上有多个事务同时执行的时候,就可能出现脏读(dirty read)、不可重复读 (non-repeatable read)、幻读(phantom read)的问题,为了解决这些问题,就有 了“隔离级别”的概念。
1.1 MySql 脏读
脏读指的是读到了其他事务未提交的数据,未提交意味着这些数据可能会回滚,也就是可能最终不会存到数据库中,也就是不存在的数据。读到了并一定最终存在的数据,这就是脏读。
1.2 不可重复读
不可重复读指的是在同一事务内,不同的时刻读到的同一批数据可能是不一样的,可能会受到其他事务的影响,比如其他事务改了这批数据并提交了
1.3 MySql 幻读
假设事务A对某些行的内容作了更改,但是还未提交,此时事务B插入了与事务A更改前的记录相同的记录行,并且在事务A提交之前先提交了,而这时,在事务A中查询,会发现好像刚刚的更改对于某些数据未起作用,但其实是事务B刚插入进来的,让用户感觉很魔幻,感觉出现了幻觉,这就叫幻读
为了解决这些问题,就有 了“隔离级别”的概念
2 MySql 隔离级别
隔离就是将事务操作隔离,相互之间不影响,隔离得越严实,效率就会越低,因此在业务开发中,需要在二者之间寻找一个平衡点,
SQL 标准的事务隔离级别包括:
- 读未提交(read uncommitted)
- 读提交(read committed)
- 可重复读(repeatable read)
- 串行化 (serializable )。
MySQL 的 InnoDB 引擎支持事务,其中可重复读是默认的隔离级别。
如这里我们有一张表
CREATE TABLE `t_user`(
`id` BIGINT(20) NOT NULL AUTO_INCREMENT ,
`id_card` VARCHAR(250) NOT NULL COMMENT '身份证' ,
`u_name` VARCHAR(250) NOT NULL COMMENT '用户姓名' ,
`u_age` INT DEFAULT '0' COMMENT '用户年龄 ' ,
PRIMARY KEY(`id`)
) ENGINE = INNODB AUTO_INCREMENT = 39 DEFAULT CHARSET = utf8 COMMENT = '用户信息表';
然后这里有一条用户数据
现在我们来修改这个用户的年龄来说明一下不同的事务隔离(修改用户的年龄为22)。
2.1 读未提交
如下图所示,若隔离级别是“读未提交”, 则 V1 的值就是 22。这时候事务 B 虽然还没有提交,但是 结果已经被 A 看到了。因此,V2、V3 也都是 22。
2.2 读提交
若隔离级别是“读提交”,则 V1 是 20,事务 B 的更新在提交后才能被 A 看到。所以,V2 、V3 的值是 22。
2.3 可重复读
若隔离级别是“可重复读”,则 V1、V2 是 20,V3 是 22。之所以 V2 还是 20,遵循的就是这个要求:事务在执行期间看到的数据前后必须是一致的。
2.4 串行化
若隔离级别是“串行化”,则在事务 B 执行“将 20 改成 22”的时候,会被锁住。直到事务 A 提交后,事务 B 才可以继续执行。所以从 A 的角度看, V1、V2 值是 20,V3 的值 是 22。
3 事务隔离的实现
在 MySQL 中,实际上每条记录在更新的时候都会同时记录一条回滚操作,记录上的最新值,通过回滚操作,都可以得到前一个状态的值。
如在可重复读隔离模式下,假设将一个值从 1 被按顺序改成了 2、3、4,在回滚日志里面就会有类似下面的记录。
完毕
不局限于思维,不局限语言限制,才是编程的最高境界。
以小编的性格,肯定是要录制一套视频的,随后会上传
有兴趣 你可以关注一下 西瓜视频 — 早起的年轻人