请选择 进入手机版 | 继续访问电脑版
查看: 43|回复: 0

[资料分享] 基于read uncommitted使用解析

[复制链接]

签到天数: 193 天

[LV.7]化身百千

发表于 2019-3-14 20:57:34 | 显示全部楼层 |阅读模式

该级别称为未提交读,即允许读取未提交的数据。

在该隔离级别下,读数据的时候不会申请读锁,所以也不会出现查询被阻塞的情况。

在会话1执行:

create table ttt(id int);
insert into ttt select 1;
insert into ttt select 2;
begin;
update ttt set id=10 where id=1;
如果会话1的隔离级别不是默认的,那么在执行update的过程中,可能会遇到以下错误:

ERROR 1665 (HY000): Cannot execute statement: impossible to write to binary log since BINLOG_FORMAT = STATEMENT and at least one table uses a storage engine limited to row-based logging. InnoDB is limited to row-logging when transaction isolation level is READ COMMITTED or READ UNCOMMITTED.
这是read committed和read uncommitted两个隔离级别只允许row格式的二进制日志记录格式。而当前的二进制日志格式记录方式为statement时就会报错。要解决这个问题,只要将格式设置为row或者mixed即可。

set @@session.binlog_format=row;
在会话2执行:

set transaction isolation level read uncommitted;
select * from ttt;
+------+
| id   |
+------+
|   10 |
|    2 |
+------+
发现查询的结果是update后的数据,但是这个数据是会话1未提交的数据。这是脏读的问题,即读取了未提交的脏数据。

如果此时会话1进行了回滚操作,那么会话2上查询的结果又变成了id=1。

在会话1上执行:

rollback;
在会话2上查询:

mysql> select * from ttt;
+------+
| id   |
+------+
|    1 |
|    2 |
+------+
这是读不一致问题。即同一个会话中对同一条记录的读取结果不一致。

read uncommitted一般不会在生产环境中使用,因为问题太多,会导致脏读、丢失的更新、幻影读、读不一致的问题。但由于不申请读锁,从理论上来说,它的并发性是最佳的。所以在某些特殊情况下还是会考虑使用该级别。

要解决脏读、读不一致问题,只需在查询记录的时候加上共享锁即可。这样在其他事务更新数据的时候就无法查询到更新前的记录。这就是read commmitted隔离级别。

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐上一条 /2 下一条

返回顶部