mysql隔离级别容易理解的方法

开始我以为图像会容易理解mysql隔离级别,后面看到这个文章,发现这个代码容易理解了,只是有些部分有小错误,和排版看的不容易,就加以修改转来了
关于mysql隔离级别的实验

简介

SQL定义了四种隔离级别。包括

  • READ UNCOMMITED(未提交读)
  • READ COMMITED(提交读)
  • REPEATABLE READ(可重复读)
  • REPEATABLE READ(可串行化)

其区别在于
表1

隔离级别脏读可能性不可重复读可能性幻读可能性加锁读
READ UNCOMMITEDYesYesYesNo
READ COMMITEDNoYesYesNo
REPEATABLE READNoYesNoNo
SERAILIZABLENoNoNoYes

个人理解,所涉及的几个名称的含义为:

  • 脏读: 在一事务中读取到其他未提交事务的数据
  • 不可重复读: 在一事务中读取到其他已提交事务的数据
  • 幻读: 在一事务中读取到其他已提交事务的新增行
  • 加锁读: 在一事务中对读取到的每一行数据都加锁

为了实验上述理解,以下建立一城市表进行各个隔离级别的仿真。
统一建立一城市表为

CREATE TABLE `isolationtest_city_innodb` (
  `id` int(11) NOT NULL DEFAULT '0',
  `name` varchar(128) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
  PRIMARY KEY (`id`),
  KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

并建立两个测试用城市:

INSERT INTO isolationtest_city_innodb(id, NAME) VALUES(131, '北京'), (289, '上海');

开启两个事务A,B。A,B的执行顺序为

时序AB
1start transaction
2start transaction
3update isolationtest_city_innodb set name = ‘成都’ where name = ‘北京’
4select * from isolationtest_city_innodb
5commit
6select * from isolationtest_city_innodb
7start transaction
8insert isolationtest_city_innodb set id = 332, name = ‘天津’
9select * from isolationtest_city_innodb
10commit
11select * from isolationtest_city_innodb
12insert isolationtest_city_innodb set id = 332, name = ‘天津’
13commit

后续实验都将建立在此基础上。

READ UNCOMMITED

根据表1所述,事务B在时序4,6,9,11上将均能获取到事务A的数据。为验证以上断言,在开启事务B前修改数据库隔离模式

set tx_isolation = 'READ-UNCOMMITTED';

READ COMMITED

根据表1所述,事务B在事务A未提交事务前是看不到事务A的数据的。据此断言对于事务B,时序4将只能看到事务B的数据;时序6能看到事务A在时序5提交的数据;时序9看不到事务A的数据;时序11可以看到事务A在时序10提交的数据。
为验证以上断言,在开启事务 B前修改数据库隔离模式

set tx_isolation = 'READ-COMMITTED';

REPEATABLE READ

根据表1所述,事务B在事务A未提交事务前是看不到事务A的数据的。据此断言对于事务B,时序4将只能看到事务B的数据;时序6能看到事务A在时序5提交的数据;时序9看不到事务A的数据;时序11可以看到事务A在时序10提交的数据。
为验证以上断言,在开启事务 B前修改数据库隔离模式

set tx_isolation = 'REPEATABLE READ';

SERIALIZABLE

SERIALIZABLE通过强制事务串行执行,避免幻读问题《高性能mysql》

也就是,事务B将在事务A结束后才得以执行。因此,事务B将在时序4阻塞;在时序6读取到‘北京’被修改为‘成都’的信息;而事务A在时序7再次阻塞。后续时序将无法继续执行。

测试得时序4,6,7的结果分别为

READ UNCOMMITED

READ COMMITED

REPEATABLE READ

SERIALIZABLE

时序结果时序结果时序结果时序结果
4+—–+——–+
| id | name |
+—–+——–+
| 131 | 成都 |
| 289 | 上海 |
+—–+——–+
4+—–+——–+
| id | name |
+—–+——–+
| 131 | 北京 |
| 289 | 上海 |
+—–+——–+
4+—–+——–+
| id | name |
+—–+——–+
| 131 | 北京 |
| 289 | 上海 |
+—–+——–+
6+—–+——–+
| id | name |
+—–+——–+
| 131 | 成都 |
| 289 | 上海 |
+—–+——–+
6+—–+——–+
| id | name |
+—–+——–+
| 131 | 成都 |
| 289 | 上海 |
+—–+——–+
6+—–+——–+
| id | name |
+—–+——–+
| 131 | 北京 |
| 289 | 上海 |
+—–+——–+
6+—–+——–+
| id | name |
+—–+——–+
| 131 | 成都 |
| 289 | 上海 |
+—–+——–+
9| id | name |
+—–+——–+
| 131 | 成都 |
| 289 | 上海 |
| 332 | 天津 |
+—–+——–+
9+—–+——–+
| id | name |
+—–+——–+
| 131 | 成都 |
| 289 | 上海 |
+—–+——–+
9+—–+——–+
| id | name |
+—–+——–+
| 131 | 北京 |
| 289 | 上海 |
+—–+——–+
11+—–+——–+
| id | name |
+—–+——–+
| 131 | 成都 |
| 289 | 上海 |
| 332 | 天津 |
+—–+——–+
11+—–+——–+
| id | name |
+—–+——–+
| 131 | 成都 |
| 289 | 上海 |
| 332 | 天津 |
+—–+——–+
11+—–+——–+
| id | name |
+—–+——–+
| 131 | 北京 |
| 289 | 上海 |
+—–+——–+
测试结果和理解上是一致的。测试结果和理解上是一致的。测试结果和预测的有所不同。在时序11中,事务B并没有读取到事务A插入的‘天津’行而产生幻读。然而,这种幻读的影响在时序12中体现出来。事务B因为事务A已插入了‘天津’行而无法重复插入相同主键行。似乎mysql只读数据过程中避免了幻读现象,而在写数据过程中却没能避免。更多的介绍可以参考MySQL的InnoDB的幻读问题_jackbillow_新浪博客以上空结果表示查询阻塞。从结果上看,和断言是一致的

总结

对SQL的四种隔离级别的理解基本正确。针对REPEATABLE READ,mysql似乎在读数据过程避免了幻读现象,然而在写数据过程上没有避免。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值