mysql事务隔离级别 - wwq0912/mysql GitHub Wiki

Transaction isolation Sector

事务隔离级别 脏读 不可重复读 幻读
读未提交(read-uncommitted)
不可重复读(read-committed)
可重复读(repeatable-read)
串行化(serializable)

1、脏读:一个事务可以读取另一个尚未提交事务的修改数据。
2、不可重复读:在同一个事务中,不同时间查询到的数据不一样. 数据可能被update/delete
3、幻读:在同一事务中,同一查询多次进行时候,由于其他插入操作(insert)的事务提交,导致每次返回不同的结果集。(其他事务划重点 )
小结:不可重复读的和幻读很容易混淆,不可重复读侧重于修改,幻读侧重于新增


读操作可以分成两类:快照读 (snapshot read)与当前读 (current read)

  • 快照读:普通的select语句 ---不加锁
  • 当前读: select * from table where ? lock in share mode; --共享锁
    select * from table where ? for update;
    insert into table values (…);
    update table set ? where ?;
    delete from table where ?;
    对于当前读,只有第一条是加共享锁 其他都是排他锁。

四钟锁 下面是表级锁类型的兼容性!

四种锁 共享锁s 排他锁x 意向共享锁is 意向排他锁ix
共享锁s 兼容 冲突 兼容 冲突
排他锁x 冲突 冲突 冲突 冲突
意向共享锁is 兼容 冲突 兼容 兼容
意向排他锁ix 冲突 冲突 兼容 兼容

shen

下面会用到锁的知识--, https://blog.csdn.net/zhongyangjian/article/details/51968675?utm_source=blogxgwz9 (好的例子!!)
例子在1.2.1 锁与索引的关系
summary:

CREATE TABLE IF NOT EXISTS `msg` (
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  `token` varchar(45) DEFAULT NULL,
  `message` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`ID`),
  KEY `FK_TOKEN` (`token`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;

不可重复读(read-committed)
它可以防止不同事务版本的数据修改提交时造成数据冲突的情况,但当别的事务插入数据时可能会出现问题。

事务A:

select * from msg where token="asd" 

result:

# ID, token, message
'4', 'asd', '订单号多少'

update msg set message='订单' where token='asd';  1 row(s) affected

事务B

insert into msg values (null,'asd','hello'); commit;

事务A

select * from msg where token="asd"; return 2 rows;

所以这里就出现了幻读

可重复读(repeatable-read) 可以避免幻读, innodb引入了gap锁。
https://www.aneasystone.com/archives/2018/06/insert-locks-via-mysql-source-code.html 在事务A执行:update msg set message=‘订单’ where token=‘asd’;
innodb首先会和RC级别一样,给索引上的记录添加上X锁,此外,还在非唯一索引'asd'与相邻两个索引的区间加上锁。
这样,当事务B在执行insert into msg values (null,'asd','hello'); 时,会首先检查这个区间是否被锁上,如果被锁上,则不能立即执行,需要等待该gap锁被释放。这样就能避免幻读问题。 (这个锁不是事务A的update执行完就可以释放的,需要是事务A结束掉)
Question: 什么叫相邻的两个索引区间??? 按什么排序的啊


======================== ok还是不懂怎么加的gap锁 好像要学B+树索引
gap的知识来了--。超棒的例子 ---http://hedengcheng.com/?p=771#_Toc374698322
相应的gap lock就是加在gap上的锁,还有一个next-key锁,是记录+记录前面的gap的组合的锁。
只有在read repeatable或者以上的隔离级别下的特定操作才会取得gap锁 (特定操作, select * for update/ locak in share mode/update/delete) 这些特殊操作除了对唯一索引的唯一搜索外(比如自增长的ID) 都会获取gap/next-key锁。 锁掉扫描范围

⚠️ **GitHub.com Fallback** ⚠️