数据库锁机制

事务的基本要素

事务是指访问并且更新数据库中的各项数据资源的一个程序执行单元,事务其实就是指数据库事务。
ACID原则是数据库事务执行的四个基本要素,分别是原子性,一致性,隔离性,持久性。

  1. 原子性:事务要么都执行,要么都不执行。
  2. 一致性:数据库在事务执行前后是一致的,比如进行转账,在事务完成后总金额应该保持一致。
  3. 隔离性:事务与事务之间是相互隔离的。
  4. 持久性:事务的提交或者回滚应该是持久保存的。

事务的隔离级别

Read-uncommitted(读未提交):一个事务可以读取另外一个事务未提交的结果。
Read-committed(读已提交):一个事务只可以读取另外一个事务已经提交的结果。
Repeated-Read(可重复读):mySql的默认隔离级别,一个事务多次查询读取的结果是一样的。
Serializable(序列化):所有事务操作按照顺序依次执行,会导致大量的超时以及锁竞争,性能最差。

不同事务级别的并发问题

读未提交:脏读,不可重复读,幻读
读已提交:不可重复读,幻读
可重复读:幻读

脏读:一个事务读取另外一个事务未提交的数据,如果此时事务回滚,读取的数据无效。
不可重复读:一个事务在重复读取数据之间,另外一个事务对数据进行了修改,两次读取的值不一致。
幻读:一个事务在重复读取数据之间,另外一个事务对对应的字段进行了增加删除等操作,两次读取的结果集不一样。

数据库锁

按照锁的粒度分:表级锁、行级锁、页面锁

表级锁:锁粒度最大的一种锁,对当前整个表进行加锁。开销小,加锁快,不会出现死锁,并发度很低,容易发生锁冲突。
行级锁:只针对当前行进行加锁。开销大,加锁慢,可能会出现死锁,并发度很高。
页面锁:介于表级锁与行级锁之间,一次锁定周围多条数据。

只有通过索引访问数据时,InnoDB才会使用行级锁,其余情况都使用表级锁。
由于行锁是针对索引加的锁,所以采用同一个索引访问不同行也有可能会发生锁冲突。
MyIsam中是不会发生死锁的,因为是表级锁一次锁住了全部数据。在InnoDB行级锁中,当两个事务同时执行,一个锁住了主键索引,在等待其他相关索引。另一个锁定了非主键索引,在等待主键索引。这样就会发生死锁。

避免死锁

1、如果不同程序会并发存取多个表,尽量约定以相同的顺序访问表,可以大大降低死锁机会。
2、在同一个事务中,尽可能做到一次锁定所需要的所有资源,减少死锁产生概率;
3、对于非常容易产生死锁的业务部分,可以尝试使用升级锁定颗粒度,通过表级锁定来减少死锁产生的概率;

行级锁:共享锁,排他锁;MVCC版本控制

InnoDB的行级锁有两种模式:共享锁与排他锁。
共享锁又称为读锁,多个事务可以共享一把锁,都可以获取数据但是不能对其进行修改。
排他锁又称为写锁,如果一个事务获取了排他锁,其他事务就不能再获取共享锁和排他锁了,获取排他锁的事务可以对其进行读和写。

InnoDB的修改操作:update,delete,insert默认是排他锁的。而普通的select查询不会加锁,select …for update会加上排他锁。select … lock in share mode会加上共享锁。

InnoDB也可以不加锁,使用版本控制来解决并发。

MVCC多版本并发控制

MVCC可以认为是行级锁的变种,可以在很多情况下避免加锁操作,因此开销更低。
MVCC是指多版本并发控制,MVCC的实现通过保存数据在某个时间的快照来实现。
在INnoDB中,每一行数据都有两个隐藏的字段,分别是当前行创建和删除的版本号。每开启一个新的事务版本号都会递增。通过这两个字段对表进行增删改查时会通过比较版本号来进行控制。
https://blog.csdn.net/w2064004678/article/details/83012387
进行插入操作时,创建版本号为当前事务的版本号。
进行更新操作时,创建版本号与原记录的删除版本号设置为当前事务版本号
进行删除操作时,删除版本号为当前事务的版本号。
进行查询操作时,应满足当前事务版本号大于或等于创建版本号,保证当前行记录肯定是存在或者只由当前事务所更新修改。删除版本号为空或者大于当前事务版本号保证该行数据不会被删除。

快照读与当前读

快照读是指读取快照版本,也就是历史版本。基于MVCC保证数据的一致性,读取数据是不需要加锁。
当前读是指通过对读取的数据进行加锁来保证数据的一致性。
普通的SELECT就是快照读,而UPDATE、DELETE、INSERT、SELECT ... LOCK IN SHARE MODE、SELECT ... FOR UPDATE是当前读。

RR可重复读隔离级别下解决幻读

在快照读情况下,使用MVCC版本控制来解决幻读。
在当前读情况下,使用next-key lock来解决幻读。
使用InnoDB下,mysql只在满足索引条件的记录上加锁,所以允许另一事务在锁定的记录旁边进行update/insert操作导致幻读。
next-key lock 使用gap lock对命中的记录行周围一定的区间加锁避免幻读。

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