mysql锁的简单想法(不确定对不对)

1. 隔离级别

1. read uncommitted

事务可以看见其他未提交事务的修改。会导致脏读。

2. read committed

事务只能看见其他提交事务的修改。但是如果事务A读取一批数据set,其他事务之后修改了这个数据set并提交(此时事务A没有提交),这时事务A再读取数据set就跟第一次读取的结果不一致。会导致不可重复读。

3. repeatable read

在事务执行过程中,重复读到的数据是一致的

4. serializable

2. 问题

1. 脏读

事务A读到了事务B未提交的数据。(read uncommitted)

2. 不可重复读

事务A第一次读取行num,此时事务B修改行num并提交,事务A再读行num,数据会发生变化。(read uncommitted, read committed)

3. 幻读

事务A第一次查询范围query_range,返回n行,此时事务B在该查询范围内插入了一行数据并提交,事务A再次查询范围query_range会看到B插入的数据。(read uncommitted, read committed, repeatable read)

The so-called phantom problem occurs within a transaction when the same query produces different sets of rows at different times. For example, if a SELECT is executed twice, but returns a row the second time that was not returned the first time, the row is a “phantom” row.

在同一个事务执行过程中,两次相同的查询,但是查询的返回数据行数不同。

隔离级别 脏读 不可重复读 幻读
read uncommitted yes yes yes
read committed no yes yes
repeatable read no no yes
serializable no no no

3. Innodb 行锁算法

1. record lock 锁住某一行

2. gap lock 锁住两行之间的间隙(不包括行本身)

3. next key lock 同时应用1,2

4. 实例

0. current read, snapshot read

1. 实例1

  • 隔离级别 repeatable read
  • 数据库 mysql innodb
CREATE TABLE `test_lock` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `a` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `a` (`a`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
mysql> select * from test_lock;
+----+------+
| id | a    |
+----+------+
|  1 |    1 |
|  2 |    2 |
|  3 |    3 |
|  4 |    4 |
|  5 |    5 |
|  6 |    6 |
+----+------+
6 rows in set (0.00 sec)

开启sessionA, sessionB

sessionA> begin;
Query OK, 0 rows affected (0.01 sec)

sessionA> delete from test_lock where a=3;
Query OK, 1 row affected (0.00 sec)

sessionA>

此时锁(行锁、gap锁)的情况如下图,标红为加锁,采用next key lock。(不光在索引a上加锁,索引a中3所对应的主键索引也会加锁,只画了索引a)
注意:这里是主键索引的顺序与a索引的顺序一致的情况。一致的情况下,新插入的4会插入在原来的4之后。我们定义函数index_key(x), 表示获取x所对应的主键索引,new(x)表示新插入的x,old(x)表示已经存在的x。如果index_key(old(4))>index_key(new(4)),那新的4是插不进去的,因为新的4会被放在老的4的前面。同理,新插入的2也有可能插入进去(只要index_key(new(2))<index_key(old(2)))。具体的例子整理后发出

lock.png

对于sessionB,插入2,3失败,插入4成功。(如图lock.png,新插入的2会被2与3之间gap锁阻止,新插入的3肯定失败,但是新插入的4就没问题)

sessionB> insert into test_lock(a) values(2);
^C^C -- query aborted
ERROR 1317 (70100): Query execution was interrupted
sessionB> insert into test_lock(a) values(3);
^C^C -- query aborted
ERROR 1317 (70100): Query execution was interrupted
sessionB> insert into test_lock(a) values(4);
Query OK, 1 row affected (0.00 sec)

2. 实例2

  • 隔离级别 repeatable read
  • 数据库 mysql innodb
    验证实例1的另一种情况。
CREATE TABLE `test_lock` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `a` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `a` (`a`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
mysql> select * from test_lock2;
+----+------+
| id | a    |
+----+------+
|  1 |    1 |
|  5 |    3 |
|  3 |    5 |
|  7 |    7 |
+----+------+
6 rows in set (0.00 sec)

开启sessionA:

sessionA> begin;
sessionA> delete from test_lock2 where a=5;

这个时候情况如下图所示:


image.png

如果按照实例1的分析,不看主键索引id,应该插入(id=4,a=3)应该会被gap锁锁定,但是事实是可以插入成功。因为插入的(i4=d,a=3)放在了(id=5,a=3)的上面。
同样的道理,不看主键索引id,通过实例1的分析,插入(id=6,a=7)应该可以插入,但是事实不行,因为(id=6,a=7)被a=5与a=7之间的gap锁阻止了。
新插入的(id=4, a=3),需要判断会插入在(id=5, a=3)之前还是之后,很明显之前(4<5),那么(id=3, a=5)与(id=5, a=3)之间的gap锁不会阻止。
新插入的(id=6, a=7),需要判断会插入在(id=7, a=7)之前还是之后,很明显之前(6<7),那么(id=6, a=7)会被(id=3, a=5)与(id=5, a=3)与(id=7, a=7)之间的gap锁阻止。

5.TODOLIST

1. 在普通索引相同、主键索引不同(废话)的情况下,order by普通索引,顺序是一定按照主键索引的顺序返回吗?(测试是这样,真要搞清楚还是要看代码)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343