mysql

mysql-隔离级别

2022-02-18  本文已影响0人  go_2021

事务隔离级别

https://mp.weixin.qq.com/s/x_7E2R2i27Ci5O7kLQF0UA
未提交读 幻读+重复读+脏读
提交读 幻读+重复读
重复读 幻读
mysql重复读解决了幻读问题,mvcc解决了快照读的幻读问题,而间隙锁解决了当前读幻读问题。
串行 (读加共享锁,写加独占锁)

一些锁

乐观锁cas原理。读version+改version+1和相关字段,失败就再再来。
独占锁 for update
一个占了,能读能写,其他都不能占。
读锁 LOCK IN SHARE MODE
一个占了,只能读,其他也能占读锁,但是写锁加不了。

窗口1:
set autocommit = 0;
start TRANSACTION;
select * from com_code where id = 3 LOCK IN SHARE MODE;
窗口2:
转呀转啊,转菊花,就是不执行。
UPDATE `ae_plat`.`com_code` SET `code` = 33 WHERE `id` = 3;

意向锁
表级别的,读锁前要加读意向锁,写锁前要加写意向锁。
比如现在有个id为3的读锁,现在要加个全表的写锁。发现已经有了读意向锁,所以等待,等读意向锁释放。
间隙锁
重复读隔离级别,引入避免幻读。
间隙锁只对于有索引的,没有索引的只能全锁。

事务测试

测试脏读


  1. 关闭自动提交,执行插入sql。
  2. 另开一个窗口,查询数据查不到此条数据,说明没有脏读问题。

测试 不可重复读


  1. 查id是58的这条数据,发现title是测试视频1111
  2. 在另外的窗口,执行update这条数据title改为6666
    然后再执行第一个窗口中的select语句,结果和原来的一样,没有变成6666说明没有不可重复读的问题。

测试幻读

窗口1:
1   1   222
2   1   11
3   1   10
5   2   9
set autocommit = 0;
start TRANSACTION;
select * from com_code where id<5;//查出3条
窗口2执行:
INSERT INTO `ae_plat`.`com_code`(`id`, `code`, `agent_id`) VALUES (4, 2, 10);
窗口1:
select * from com_code where id<5;//再次执行,结果还是3条,不存在幻读问题

mysql避免幻读相关

快照读(mvcc实现)
上面例子,窗口1里的select就是快照读,快照读会读本事务里的快照数据就是缓存,不会读到当前数据里的id为4数据。
当前读
增删改,是当前读,不读缓存,如果把select改为update所以数据的code为5。最后新插入的那条数据code就会变成5。
mysql比sql标准厉害,rr级别也可以避免幻读,但是存在增删改这种当前读的情况,还是会发生幻读。
怎么避免当前读的幻读问题呢?加锁。

set autocommit = 0;
start TRANSACTION;
select * from`ae_plat`.`com_code`   WHERE `id` < 5 for update;

这时候执行insert插入,就会菊花转呀转。这咋实现的,这就是间隙锁,对不存在的数据加锁,然后再去执行update,提交事务,就不会把新插入的数据也修改了,这就是利用间隙锁避免当前读出现幻读问题的实现。

一些命令

1:查看当前的事务
SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX;
杀死事务进程id(就是上面命令的trx_mysql_thread_id列)
2:查看当前锁定的事务
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;
3:查看当前等锁的事务
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;

上一篇下一篇

猜你喜欢

热点阅读