Mysql隔离级别

2019-10-29  本文已影响0人  白驹过隙_忽然而已

打死记不住的隔离级别,笨人需要多动笔,写个笔记先。

【原】=========> 巨人的肩膀

  1. Read uncommitted (读取未提交的内容)
    一个事务可以看到其他事务未提交的处理结果。会导致脏读。
  2. Read committed
    一个事务只可以看到其他事务提交的处理结果。大多数据库的默认隔离级别,但MySQL不是
  3. Repeatable read
    保证一个事务中相同查询返回的结果一定是相同的,但是会有幻读的问题。是MySQL的默认隔离级别。
  4. Serializable
    事务串行化,会出现大量超时、锁竞争。

潜在问题:
脏读:事务A读取了事务B未提交的处理结果,此时事务B回滚了操作,事务A读取到的就是错误的脏数据。
幻读:

实践检验:
查询当前会话事务隔离级别:

select @@transaction_isolation;
select @@transaction_isolation

(注:简书上传图片,直接修改连接后数字改变图片大小)
查看系统隔离级别:

select @@global.transaction_isolation
select @@global.transaction_isolation

开启两个会话A/B 修改隔离级别,然后模拟事务操作,在B中查询数据

修改当前会话隔离级别
set session transaction isolation level read uncommitted;
修改系统隔离级别
set global transaction isolation level read uncommitted;

设置隔离级别为read uncommitted(读未提交);

开启事务,更新数据,不提交


初始数据
开启事务,修改数据,不提交
会话B 查询已经可以看到修改结果

此时A rollback,B就读到了脏数据。

设置隔离级别为read committed(读已提交);

会话A 开启事务,修改数据,不提交
会话B 中查询,数据未更改
会话A commit
会话B查询,数据更改

read commited级别下,一个事务只可以访问到其他事务已经提交的更改,解决了脏读问题。但是会话B两次查询的结果不一致,所以read committed 级别可能导致在一个事务范围下,相同的查询可能出现不同的结果,就是不可重复读。

设置隔离级别为repeatable read(可重复读);

数据初始状态
开启事务,修改数据,不提交
会话B 开启事务,查询不到更新的数据
会话A commit
会话B 还是读不到更新的数据

这就解决了不可重复读的问题,保证了一个事务范围内,同一个查询返回的结果一样。
但是此时插入一条数据并提交


会话A 插入数据并提交
会话B 也读不到这条数据
会话B commit 结束此次事务后,才可以查询到会话A 更新和插入的数据
可重复读解决了不可重复读的问题,但是会有 幻读的问题。

设置隔离级别为Serializable(串行化)

会话B 开启事务,查询数据初始状态
会话A 会进入等待状态,因为会话B的事务没有提交
会话B commit
会话A 提交成功
时间太长就会超时
上一篇下一篇

猜你喜欢

热点阅读