概述
本文将讲述mysql事务隔离的实现。
隔离性与隔离级别
隔离级别 | 含义 |
---|---|
读未提交 | 一个事务还没提交时,它做的变更就能被别的事务看到 |
读提交 | 一个事务提交之后,它做的变更才会被其他事务看到 |
可重复读 | 个事务执行过程中看到的数据,总是跟这个事务在启动时看到的数据是一致的。在可重复读隔离级别下,未提交变更对其他事务也是不可见的 |
串行化 | 针对同一行记录,如何读或写,都会加锁。后访问的事务必须等前一个事务执行完成,才能继续执行 |
实例分析
我们知道,单单说概念都是很枯燥的,很容易云里雾里。因此,我们来举一个简单的例子来说明上述四种隔离级别的区别吧。 假设数据表T中只有一列,其中一行的值为1。
mysql> create table T(c int) engine=InnoDB;
insert into T(c) values(1);
下面按照时间顺序执行两个事务:
接下来我们来讨论下,在不同的事务隔离级别下,V1、V2、V3的值都是什么。
- 读未提交 事务B将值改为2,V1的值是2,因为读到了未提交的值。V2和V3的值也都是2。
- 读提交 V1的值是1,V2和V3的值都是2,因为事务B的更新只能提交之后才能看到。
- 可重复读 V1、V2的值是1,V3的值是2,因为事务在执行期间看到的数据前后必须是一致的。
- 串行化 V1、V2的值是1,V3的值是2,因为事务A查询时,获取了锁,事务B被锁住了,等到事务A完成了之后才能执行。
事务隔离的实现原理
在实现上,数据库里面会创建一个视图,访问的时候以视图的逻辑结果为准。
隔离级别 | 视图创建时机 |
---|---|
读未提交 | 没有视图概念,直接返回记录的最新值 |
读提交 | 每个SQL语句开始执行时 |
可重复读 | 事务启动时 |
串行化 | 直接用加锁的方式来避免并行访问 |
事务的启动方式
- 显示启动 begin 或 start transaction。配套的提交语句是commit,回滚语句是rollback。
- 关闭自动提交 set autocommit=0,关闭自动提交事务,主动执行commit 或 rollback 语句。