目录
什么是事务
事务的特性
事务并发产生的问题
事务隔离级别
事务隔离级别的实现
MVCC
Read View(一致性视图)
锁(LBCC)
锁的算法
事务就是一条sql语句或者多条sql语句所组成的逻辑执行单元,要么全部执行成功要么全部执行失败,目的是保证数据的一致性。
并不是所有的存储引擎都支持事务,InnoDB,NDB是支持事务的。
在Mysql中事务的四大特性主要包含:原子性(Atomicity)、一致性(Consistency)、隔离性(lsolation)、持久性(Durability),简称为ACID。
原子性、隔离性、持久性都是为了保障一致性而存在的,一致性也是最终的目的。
脏读:一事务对数据进行了增删改,但未提交,另一事务可以读取到未提交的数据。如果第一个事务这时候回滚了,那么第二个事务就读到了脏数据。
不可重复读:一个事务中发生了两次读操作,第一次读操作和第二次操作之间,另外—个事务对数据进行了修改,这时候两次读取的数据是不一致的。(update/delete)
幻读:第一个事务对一定范围的数据进行批量修改,第二个事务在这个范围增加一条数据,这时候第一个事务就会丢失对新增数据的修改。(insert)
在Mysql中事务的隔离级别分为四大等级,读未提交(READ UNCOMMITTED)、读提交 (READ COMMITTED)、可重复读 (REPEATABLE READ)、串行化 (SERIALIZABLE)。MySql默认的隔离级别是可重复读。
读未提交:可以读取另一个事务没有提交的数据。没有解决任何并发问题
读已提交:读取最新数据,可以读取另一个事务提交了的数据。解决了脏读问题。
可重复读:在同一个事务中多次读取同样的数据结果是一样的。解决了脏读和不可重复读,没有解决幻读。
串行化:最高的隔离级别,通过强制事务的串行执行。没有并发性可言,性能差。
InnoDB存储引擎在RR级别就解决了幻读问题。
Read Uncommited :不加锁
Serializable:所有的select语句都会被隐式的转化为select ... in share mode,会和update.delete互斥。
RR 与 RC
RR | RC | |
普通的select(快照读) | MVCC | MVCC |
加锁的select和更新(当前读) select ... in share mode select ... for updateinsert delete |
Record Lock Gap Lock |
Record Lock |
RC和RR的主要区别:
多版本并发控制,也叫快照读,非阻塞读。
lnnodb为每行记录都实现了三个隐藏字段
快照读效果:建立了一个快照,同一个事务无论查多少次都是相同的数据。
一个事务能看到的数据版本:
一个事务不能看见的数据版本:
MVCC基于Read View和undo log来实现
RR的 Read View是事务第一次查询的时候建立的。
RC的 Read View是事务每次查询的时候建立的。
m_ids{}里是活跃的事务id,也就是还没提交的事务
min_trx_id是m_ids里子最小的事务id,也就是未提交事务的最小id,所以小于它的一定都提交了
max_trx_id是m_ids里子最大的事务id+1(代表即将分配的id),所以大于它的是生成ReadView之后才开启的事务,所以是读不到了。
creator_trx_id是生成ReadView事务的id,也就是当前事务的id.
Read View判断规则
锁的本质是什么:锁的本质是锁索引,如果非索引的字段加锁会导致锁表。
锁的粒度
MyISAM和InnoDB分别支持什么粒度的锁?
InnoDB支持行锁和表锁,而MyISAM只支持表锁。
表锁与行锁的区别:
InnoDB锁类型
.共享锁
又称为读锁,简称S锁,顾名思义,共享锁就是多个事务对于同一数据可以共享一把锁,都能访问到数据,但是只能读不能修改;
加锁释锁方式:
select * from student where id=1 LOCK IN SHARE MODE;
锁会在事务提交或者回滚时释放,或者当连接断开也会释放锁。
拿不到锁的事务会等待,默认等待50s
排他锁
又称为写锁,简称X锁,排他锁不能与其他锁并存,如一个事务获取了一个数据行的排他锁,其他事务就不能再获取该行的锁(共享锁、排他锁),只有该获取了排他锁的事务是可以对数据行进行读取和修改。
加锁释锁方式:
自动: delete / update / insert 默认加上X锁;
手动: select* from student where id=1 FOR UPDATE;
意向锁
意向锁是由数据引擎自己维护的,用户无法手动操作意向锁。
在我们加行锁的时候,存储引擎会帮们加上表锁。(这大大提高了加表锁的效率)
意向共享锁(Intention shared Lock,简称IS锁)表示事务准备给数据行加入共享锁,也就是说一个数据行加共享锁前必须先取得该表的IS锁。
意向排他锁(Intention Exclusive Lock,简称IX锁)表示事务准备给数据行加入排他锁,说明事务在一个数据行加排他锁前必须先取得该表的IX锁。
死锁的避免
记录锁(Record):在指定的一行数据加记录锁
间隙锁(Gap):在范围加锁时,范围内没有数据,会给这个间隙加间隙锁。间隙锁的最大作用就是阻塞插入,可以解决幻读问题。
临建锁(Next-key):记录锁+间隙锁。范围加锁时,范围内有数据,会加临建锁,
记录锁
间隙锁
临建锁
select * from t2 where id>1 and id <7 for update;
锁住的范围是(1, 7]
select * from t2 where id>1 and id <=7 for update;
锁住的范围是(1, 10]