MySQL事务和锁——《MySQL DBA工做笔记》

MySQL事务

事务存在的缘由

事务存在的目的:保证用户对数据操做对数据是安全的。(好比说银行卡余额)mysql

事务的特性——ACID

原子性:一个事务要么所有执行,要么不执行面试

一致性:事务开始和结束时,数据保持一致sql

隔离性:事务之间互不影响数据库

持久性:事务操做的结果具备持久性编程

关于脏读,不可重复读,幻读

  • 脏读安全

    事务A读取了事务B中还没有提交的数据。若是事务B回滚,则A读取使用了错误的数据。并发

    【一个事物在读的时候,禁止读取未提交的事务】高并发

  • 不可重复读性能

    不可重复读是指在一个事务范围内屡次查询却返回了不一样的数据值,这是因为存在查询间隔,被另外一个事务修改并提交了。优化

    【一个事物在读的时候,禁止任何事务写】

  • 幻读

    在事务A屡次读取过程当中,事务B对数据进行了新增操做,致使事务A屡次读取的数据不一致。

    【一个事物加上表级锁,禁止任何操做的并发】

小结:

脏读是读取了还没有提交的数据,不可重复读是读取了不停更新的数据(修改),幻读是指读取了不停更新的数据(新增)。

关于事务隔离级别

目的:避免脏读,不可重复读,幻读

读未提交:一个事务能够读到另外一个事务还没有提交的数据。也就是脏读,避免脏读的方式:

读提交:一个事务要等另外一个事务提交后才能读取数据。但会致使一个事务中相同查询出现不一样的结果。也就是不可重复读。避免不可重复读的方式:

重复读(RR,MySQL默认级别):就是在开始读取数据时,不容许修改操做。但会致使因为容许insert操做致使的事务结果出现不一样。也就是幻读,避免幻读的方式::

序列化:序列化使事务串行顺序执行,但会大大下降并发性能。

MySQL锁机制

Innodb实现了两种类型的行锁:共享锁,排他锁。

共享锁和排他锁

共享锁:容许一个事务读一行,阻止其余事务得到相同数据集的排他锁,多个共享锁是能够并行的。

排他锁:获取排他锁的事务容许更新数据,阻止其余事务获取相同数据集的共享锁和排他锁。

【复述一下】

假设事务A获取了表中的行666,就至关于得到了共享锁,此时A能够读取数据,其余事务也能够得到行666的共享锁,因此多个共享锁是能够并行指的是多个事务能够读取相同的行,可是一旦某行被获取了共享锁,就没法被其余事务获取排他锁,也就是说,行只能读,不能写。

而后A读完了,事务B要对行666进行更新操做,就须要先得到排他锁,得到排他锁以后,其余事务就没法获取行666的排他锁和共享锁,也就是说,在事务B更新数据的时候不容许其余事务读或者更新。

因此排他锁就是指只容许一个事务进行写操做,在这个过程当中,不容许其余事务读,也不容许其余事务写。

也就是说,排他锁是串行的,不能被多个事务同时持有,但共享锁能够。

【如何使用行锁】

InnoDB行锁是经过索引上的索引项来实现的,InnoDB这种行锁实现特色意味者:只有经过索引条件检索数据,InnoDB才会使用行级锁,不然,InnoDB将使用表锁!(这也是为何须要进行索引优化的缘由)

【行锁定的范围问题】

行锁:对索引项加锁,锁定一条记录

间隙锁:

编程的思想源于生活,生活中的例子能帮助咱们更好的理解一些编程中的思想。
生活中排队的场景,小明,小红,小花三我的依次站成一排,此时,如何让新来的小刚不能站在小红旁边,这时候只要将小红和她前面的小明之间的空隙封锁,将小红和她后面的小花之间的空隙封锁,那么小刚就不能站到小红的旁边。
这里的小红,小明,小花,小刚就是数据库的一条条记录。
他们之间的空隙也就是间隙,而封锁他们之间距离的锁,叫作间隙锁。

间隙锁的目的是为了防止幻读

innodb自动使用间隙锁的条件:

  • 必须在RR级别下
  • 检索条件必须有索引(没有索引的话,mysql会全表扫描,那样会锁定整张表全部的记录,包括不存在的记录,此时其余事务不能修改不能删除不能添加)

Next-key Lock:等于行锁加间隙锁。扫描索引记录后,先对索引记录加上行锁,再对索引两边的间隙加上间隙锁。

意向共享锁和意向排他锁

Innodb虽然使用行锁,但并无废弃表锁。

行锁和表锁】

MyISAM存储引擎使用的是表锁,而Innodb增长了行锁。并不意味着Innodb完全抛弃了表锁。

关于行锁,较小的粒度致使其高并发,但也因较小的粒度致使加锁慢,开销大,会出现死锁状况。

关于表锁,较大的粒度在高并发上的表现很弱,但同时粒度较大,加锁块,开销小,不会出现死锁状况。

没有完美的技术,只有合适的解决方案。在高并发场景下使用行锁而忍受一些问题本质上是一种权衡。

意向锁的背景冲突】

意向锁的出现本质上是解决行锁和表锁矛盾的问题。

事务A得到了表中某一行的共享锁,事务B申请了表的写权限,这时候就会产生矛盾。

关于意向锁】

首先,意向锁是一种表锁。

意向共享锁:事务得到表中的某一行的共享锁前,须要先得到整张表的意向共享锁。

意向排他锁:事务得到表中的某一行的排他锁前,须要先得到整张表的意向排他锁。

意向锁的加锁过程是自动完成的。

【意向锁的共享问题】

意向锁是表锁,它的互斥性是针对表级别的事务,好比一个事务要获取一张表的写权限。因此意向锁对于表级别的事务是互斥的。可是对于行级别的事务是共享的,也就是说,一个意向锁能够被多个行级别的事务所持有。

死锁

关于死锁抖音上有一个很是好玩的小视频:

面试官问:解释一下死锁,解释明白了就发offer

应聘者答:先发offer,发了offer再解释

死锁本质上就是持有锁和释放锁的问题,就像这个视频里描述的,面试官在听到死锁的解释后,才会释放offer这个锁,而应聘者是获得offer后才会释放死锁解释这个锁。offer和对死锁的解释就能够类比两个锁。

死锁的状态就是互相等待。

相关文章
相关标签/搜索