mysql isolation_mysqltx_isolation

mysql事物隔离级别分为四种, (文档)

READ-UNCOMMITTED READ-COMMITTED REPEATABLE-READ SERIALIZABLE

接下来会通过实践,来逐步介绍四种隔离级别的作用。mysql默认的隔离级别为repeatable-read。可通过select @@tx_isolation查看。如下图所示:

3c500b89d499ac162a8b0b7c941b0e09.png

tx_isolation是mysql system variables, 其余system varaiables可通过官方文档查看。

READ-UNCOMMITTED

该事物隔离级别可读取其它事物未提交的结果

通过mysql -u username -p password 开启两个mysql连接, 分别为A连接, B连接。输入set tx_isolation = 'read-uncommitted';将A连接的事务隔离级别设置为READ-UNCOMMITTED 在A,B连接的窗口分别查询test1表的数据, 表数据一致, 如下图所示

f338db2a2c0efb22d120d4c647ca7ce1.png

在B连接的命令窗口输入start transaction;,并更新相应记录, 但不提交,如下图所示

a570d154135a619cdf3ee41faf3a996a.png

在A连接的命令窗口查看test1表, 结果如下图所示

dccd7ca31a079fdaa4da101484e49b4a.png

通过结果发现。B连接,开启事物,修改数据,并未提交,A连接在read-uncommitted的隔离模式下仍然可以看到已更新的数据。 B连接窗口输入rollback回滚数据,此时A,B连接所查询的数据,和初始时的数据是一样的。

READ-COMMITTED

该事物隔离级别只会读取已提交的数据,在事务中已更改但未读取的数据不会读取

同上A,B 两个连接输入set tx_isolation = 'read-committed';将A连接的事务隔离级别修改 B连接窗口开启事务,更新数据,但不提交,如下图所示

a4800d671fc52a852589b7d385b0f3cb.png

在B连接窗口查看数据已变更在A连接窗口查看test1表格,如图

be15edfa4e4988d90932d4ba4deb7766.png

从结果可以看出A连接并未读取到B连接事务内未提交的更新数据在B连接窗口提交事务,再到A连接窗口查看, 如图

ed3b8f8f6a09ddac1dec992834944913.png

A连接可以读取到B连接已提交的数据

REPEATABLE-READ

该事务隔离级别只会读取已提交的结果,与READ-COMMITTED不同的是,repeatable-read在开启事务的情况下,同一条件的查询返回的结果永远是一致的,无论其它事物是否提交了新的数据

和READ-COMMITTED的实验环境差不多,此时将A的隔离级别改为 repeatable-read,B还是一样开启事物,更新数据, 此事暂时不提交。但A开启事物查询数据。如图

B连接

1cbc279fd18e2b5dcdd21dab33494e57.png

A连接

7196dc3a167f7464496d75b8596dbdad.png

如结果所示,B未提交的数据,A读取不到

此时B提交事物, A继续查询,会发现A仍然读取不到B已提交的结果,这就是所谓的可重复读,如下图所示

B连接

cb1dd1a958e74fa8750c739536b75309.png

A连接

a4f58107d7a869803cf3f2535699b5c8.png

此事A提交事物,在查看会查询到B更改的结果,如图

f5ca88ea75977aed284833889a42b975.png

SERIALIZABLE

这种隔离级别和repeatable-read类似,只会读取其它事物已提交的内容,有一点不同的地方在于,如果autocommit为false,那么每一条select语句会自动被转化为select ... lock in share mode.这样出现一些阻塞情况

English Explanation

This level is like REPEATABLE READ, but InnoDB implicitly converts all plain SELECT statements to SELECT ... LOCK IN SHARE MODE if autocommit is disabled. If autocommit is enabled, the SELECT is its own transaction. It therefore is known to be read only and can be serialized if performed as a consistent (nonlocking) read and need not block for other transactions. (To force a plain SELECT to block if other transactions have modified the selected rows, disable autocommit.)

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

4e15badf913d3ccb1d8f78d98bdb8711.png

A 隔离级别改为serializable, 并且开启事务或者将autocommit设置为0, 并查询被修改数据,如图

B

7ec335b37c8d114d3f1d4372a257b0ce.png

A(已经将autocommit设置为0)

2895f4d62bbedd20f2df6feb1cfaa472.png

结果表明A连接被阻塞住了, 同样的,如果A开启事务先查询, 未提交, B再去更新一样会被锁住。并且如果细心观察会发现,会发现很奇怪,按理来说lock in share mode应该是行锁定, 但是在我的机器上却成了表锁定,B只更新了id为4的记录,A查询ID为2的记录却仍然被锁定, 经过我测试在服务器上lock in share mode 确实是行锁定。经过多次测试发现如果查询数据中通过索引查询那么lock in share mode会根据索引锁行,如果查询条件中没有索引那么就直接锁表。

tips:serializable模式下, 如果设置了autocommit=0那么,会默认将select语句转为lock in share mode格式。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值