readView
对于使用read uncommitted隔离级别的事务来说,直接读取记录的最新版本就好了,对于使用serializable隔离级别的事务来说,使用加锁的方式来访问记录。对于使用read committed和repeatable read隔离级别的事务来说,就需要用到版本链,核心就是需要判断版本链中的哪个版本是当前事务可见的。
ReadView中比较重要的4个内容:
- M_ids:表示在生成readview时当前系统中活跃的读写事务的事务id列表。
- Min_trx_id:表示在生成readview时当前系统中活跃的读写事务中最小的事务id,也就是m_ids中的最小值。
- Max_trx_id:表示生成readview时系统中应该分配给下一个事务的id值。
- Creator_trx_id:表示生成该readview的事务的事务id。
注意: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,这样在访问某条记录时,只需要按照下边的步骤判断记录的某个版本是否可见:
- 如果被访问版本的trx_id的属性值等于readview中的create_trx_id值,意味着当前事务在访问它自己修改过的记录,所以该版本可以被当前事务访问。
- 如果被访问版本的trx_id的属性值小于readview中的min_trx_id值,表明生成该版本的事务在当前事务生成readview前提交,所以该版本可以被当前事务访问。
- 如果被访问版本的trx_id的属性值大于readview中的max_trx_id值,表明该生成版本的事务在当前事务生成readview后才开启,所以该版本不可以被当前事务访问。
- 如果被访问版本的trx_id的属性值在readview中的min_trx_id值和max_trx_id值之间,那需要判断属性值是否在m_ids列表中,如果在,说明创建readview时生成该版本的事务还是活跃的,该版本不可以被访问;如果不在,说明创建readview时生成该版本的事务已经被提交,如果在,说明可以被访问。
欢迎批评指正,提出问题,谢谢!