mysql的事务以及锁

一、事务的特性(ACID),原子性,一致性,隔离性,持久性;

二、Mysql的事务隔离级别

1、读未已提交(READ UNCOMMITTED):

      一个事务可以读取到未提交的数据(比如只进行了更新操作),产生脏读,幻度。

2、读已提交(READ COMMITTED):

     事务读取到已经提交的数据,多次select,查询结果不一致,产生幻度。

3、可重复读(REPEATABLE READ) :

    一个事务中多次读取数据相同,可能产生幻读,但是mysql的可重复读解决了幻读的问题,事务读取可以分为:快照读使用与select 语句,比如:select id from user where id = 1 (MVCC:READVIEW 和 版本链解决)、当前读,比如:select id from user where id = 1 for update (一个事务内读取数据,间隙锁),可以参考一下链接加深理解:https://blog.csdn.net/qq_40918324/article/details/104617714

4、串行化(SERIALIZABLE):

三、1、 什么是版本链:

 在innoDB存储引擎的表,有三个隐藏列分别是:row_id,trx_id,roll_pointer,其中row_id不是必要的,如果有主键索引,则列号不一定存在。

trx_id:记录当前事务的事务号。

roll_pointer:指向前一个事务号,(通过指针找到修改前的记录)。

2、ReadView:

①  对于读已提交和可重复读,需要使用上述的版本链,核心问题:找到哪个事务是正确的,可见的。那么怎么判断哪个事务版本是可用的呢,就需要ReadView了,我发现其实很多人都在说mvcc但是却不知道readView,真的是很奇怪。

②  ReadView 主要由四部分组成:

    1、m_ids:记录当前活跃的所有事务,相当于一个数组,[1,2,3,4]

     2、min_trx_id: 记录当前活跃事务中最小的事务号。

     3、max_trx_id:记录下一个应该开启的事务的事务号,事务号是递增的,其实就是时间戳。

     4、creator_trx_id:表示生成该ReadView的事务号。

注意max_trx_id并不是m_ids中的最大值,事务id是递增分配的。比方说现在有id为1,2,3这三个事务,之
后id为3的事务提交了。那么一个新的读事务在生成ReadView时,m_ids就包括1和2,min_trx_id的值就是1,
max_trx_id的值就是4。
③ 有了readView之后,再查询语句的时候就可以判断哪些事务的数据是可以被查到的了:
    1、比如查询的数据的事务id  <  min_trx_id  表示数据在查询前没有操作过,可以操作。
     2、如果数据的事务id == creator_trx_id 则表示当前事务在查询数据,可以操作。
     3、如果数据的事务id > max_trx_id 则表示查询时,数据又被其他的事务操作过,不能查询数据,需要根据版本链查询。
     4、如果min_trx_id < 数据的事务id <max_trx_id, 需要判断是否在m_id,并且不在m_id 列表中则代表,查询时已经被提交过,可以查询。

④ 对于读已提交和可重复读,在生成ReadView的规则不同,导致了他们读取数据时候的区别:

   1、读已提交:每次执行select的时候都会生成一个readView,记录当前活跃的事务id。所以他可以读取到最新的别提交过的数据。

   2、可重读度:他只会在第一次执行select 语句的时候生成ReadView,所以多次执行ReadView相同所以查询数据相同。

四、mysql innoDB的行锁与表锁

 一、行锁:

      1、行锁分为: ① LOCK_REC_NOT_GAP:单个行记录上的锁。   

                ② LOCK_GAP:间隙锁,只会锁住查询数据之间的间隙。

                ③ NEXT_KEY_LOCK:结合单行锁和间隙锁的锁。

       2、对于读已提交,不存在间隙锁,只会对表中查询出来的数据加锁。

       3、对于可重读度,对于主键索引和二级索引不会加间隙锁。对于普通索引和没有索引的列,会对查询出来的数据的间隙加锁(可能会造成死锁)。

       4、这里的锁对于二级索引,首先会对索引字段加锁,再下来同时会对,索引页中的主键id进行加锁,为什么会加两次锁?

           ① 当查询数据有二级索引列时,直接判断加锁快速返回。

           ② 当当前查询没有二级索引列,但是时主键索引对应的数据时,保证数据被加锁。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章