MYSQL的事务和锁

一、事务

1、ACID特性

原子性: 一个事务要么全部执行,要么完全不执行
一致性: 事务再开始和结束时,应该始终满足一致性
隔离性: 在事务操作时,其他事务的操作不能影响到当前操作(比如取钱时有人同时转账过来,不应拒绝这样的操作)
持久性: 事务操作的结果是具有持久性的

2、InnoDB的MVCC并发管理

快照读:读取的是数据的可见版本,是数据的历史镜像,这个过程是不加锁的
当前读:读取的是最新的版本,会加上锁,保证其他事务不会再修改这条记录

MVCC在数据声明周期管理里有两个重要的标识,一个是标识数据变化的,一个是标识数据可用状态的
Update:先把当前记录标识为已删除,然后新增一列数据,
Delete:把当前记录标识为已删除

3、事务回滚(InnoDB)

行数据有三个内部属性列
DB_TRX_ID:记录每一行最近一次修改它的事务ID
DB_ROLL_PTR:记录指向回滚段undo日志的指针
DB_ROW_ID:当写入数据时,自动维护的自增列
redo中顺序记录insert、delete、update操作,同时生成undo记录,为逆操作的delete、insert、update

4、事务隔离级别

查看隔离级别的方法:
SELECT @@global.tx_isolation
SELECT @@session.tx_isolation
SELECT @@tx_isolation
RC(Read-Committed)不可重复读:Oracle默认隔离级别,事务1未关闭时,事务2修改或插入数据并提交后,事务1查询结果会随着事务2的提交而变化。
RR(Repeatable-Read)可重复读:MySQL默认隔离级别,事务1未关闭时,事务2修改或插入新数据并提交后,事务1前后查询结果一致,直到关闭事务重新查询才能看到事务2更新后的数据。

RR隔离级别下的unique失效:事务1未关闭时,事务2删除原表中的一条数据,此时是事务1仍能看到已被删除的数据,此时事务1插入一条和原数据主键不冲突,唯一性索引unique冲突的数据时,确可以成功插入。
RR隔离级别下的更新冲突:事务1未关闭时,事务2插入一条数据并提交,此时事务1看不到事务2插入的数据,但此时如果update事务提交的数据,是可以成功update的,且可以查看修改后的新增数据;此时若事务2未关闭,看到的是事务1未update的数据。

5、共享锁、排它锁和表级意向锁

共享锁(S):允许一个事务去读一行,阻止其他事务获得相同数据集的排它锁。
排它锁(X):允许获得排它锁的事务更新数据,但是阻止其他事务获得相同数据集的共享锁和排它锁。
共享锁(S)之间不互斥,读读操作可以并行
排它锁(X)是互斥关系,读写,写写操作不可以并行

事务A和B,事务A锁住了表中的一行,加了行锁S,只能读不能写,之后事务B申请整个表的写锁,理论上能更改任意一行,包括S那一行,但此时和事务A就冲突了。
表级意向锁主要解决这个冲突,事务A必须先申请一个意向共享锁(IS),事务B申请X时,发现表上已经有IS了,则事务B会阻塞。
意向共享锁(IS):表示事务准备给数据行加入共享锁,也就是说一个数据行加共享锁前必须先取得该表的IS锁。
意向排它锁(IX):表示事务准备给数据行加入排他锁,说明事务在一个数据行加排它锁前必须先取得该表的IX锁。

6、行锁

InnoDB行锁是通过给索引项加锁实现的,如果没有索引,会通过隐藏的聚簇索引来对记录加锁,如果不通过索引条件检索数据,那么InnoDB将对表中所有数据加锁,实际效果跟表锁一样。
行锁(Record Lock):对索引项加锁,即锁定一条记录;
间隙锁(Gap Lock):对索引项之间的间隙、对第一条记录前的间隙或最后一条记录后的间隙加锁,即锁定一个范围的记录,不含记录本身;
Nest-key Lock:锁定一个范围的记录并包含记录本身。

7、锁的兼容性

意向锁之间是互相兼容的,S锁之间是互相兼容的,X锁和所有锁冲突
	X	S	IX	IS
X	冲突	冲突	冲突	冲突
S	冲突	兼容	冲突	兼容
IX	冲突	冲突	兼容	兼容
IS	冲突	兼容	兼容	兼容

8、死锁

如果锁不兼容的情况下,通常会产生阻塞。

9、索引加锁过程的差异

对于唯一性索引和主键,加锁过程的差异
RC隔离级别:
对于非唯一性索引来说,加锁会有2个X锁,一个位于唯一性索引的键值记录,另一个则根据对应的聚簇索引的键值(如主键索引)加X锁;
对于非唯一性索引来说,也会关联锁定的相应的主键聚簇索引项。
RR隔离级别:除了上诉2个X锁,还有额外的意向锁。

  

  

  

 

  

posted @ 2020-07-01 17:37  suminem  阅读(137)  评论(0编辑  收藏  举报