MySQL(七)之InnoDB存储引擎中的锁

锁:

锁是数据库系统与文件系统的区别的一个关键特性,锁机制用于管理对共享资源的并发访问。

latch:闩锁(轻量级锁),要求锁定的时间必须非常短。分为(互斥锁,读写锁)对象是线程。

lock:对象是事务,用来锁定数据库中的对象,如表,行,页分为(共享锁,排他锁)

MySQL(七)之InnoDB存储引擎中的锁_第1张图片

 

 Lock:

共享锁S(读锁):允许事务读取一行数据,select 不加锁

对于普通 SELECT 语句,InnoDB 不会加任何锁 将查找到的数据加上一个S锁,允许其他事务继续获取这些记录的S锁,不能获取这些记录的X锁(会阻塞) 将查找到的数据加上一个X锁,不允许其他事务获取这些记录的S锁和X锁。

排他锁X(写锁):允许事务删除或更新一行数据 ,加锁select * from table for uodate;不允许其他事务获取记录的S锁和X锁

DELETE:删除一条数据时,先对记录加X锁,再执行删除操作。

INSERT:插入一条记录时,会先加隐式锁 隐式锁来保护这条新插入的记录在本事务提交前不被别的事务 访问到。

UPDATE :如果被更新的列,修改前后没有导致存储空间变化,那么会先给记录加X锁,再直接 对记录进行修改。

        如果被更新的列,修改前后导致存储空间发生了变化,那么会先给记录加X锁,然后 将记录删掉,再Insert一条新记录。

 

意向锁:事务希望在更细粒度上进行加锁操作。

意向共享锁IS:事务想要获取一张表中某几行的共享锁。

意向排他锁IX:事务想要获取一张表中某几行的排他锁。

 

行锁:

行锁的算法:

Record Lock:单个记录上的锁

Gap Lock:间隙锁,锁定一个范围,但不锁定记录本身。为了防止同一事务的两次当前读,出现幻读的情况。

Next-Key Lock:锁定一个范围,包含锁定记录本身,解决幻读

 

锁带来的问题:

1脏读:脏页(缓冲池中已经被修改的页,还没刷新到磁盘中,数据库实例内存中的页和磁盘上页的数据不一致),脏读:事务对缓冲池中行记录的修改,并且还没有提前,被其他事务读取到称为脏读

2不可重复度:在一个事务内多次读取同一个集合,A事务还没有提交,B事务对数据做了DML,因此在第一个事务A的两次读取中数据不一致

3丢失更新:A更新未提交,B也更新,最后A提交,B提交,A提交的数据被覆盖(是数据库的任何隔离级别下不会出现丢失)

 

悲观锁

悲观锁用的就是数据库的行锁,认为数据库会发生并发冲突,直接上来就把数据锁住,其他事务不能修改,直至 提交了当前事务。

乐观锁

 var localVersion=select version from tableA where code='123';

//localVersion=1

线程A set money=money-10,version=localVersion+1 where version=localVersion and code='123';

线程B set money=money-10,version=localVersion+1 where version=localVersion and code='123' ;


线程A和B同时只能有一个更新成功,当线程A更新成功 version=2 ,线程B where条件不成立,更新失败 
另外 money=money-10 等于原子操作 

 

你可能感兴趣的:(MySQL(七)之InnoDB存储引擎中的锁)