隔离级别可重复读mysql行锁

mysql隔离级别

innodb默认隔离级别可重复读,那么可重复读究竟是什么样的?怎么实现的?
可重复读简单理解就是给当前事务开辟了一个新的空间,主数据源备份到该空间,事务没提交时都是读取该空间的数据,当提交后才继续读取主数据源数据
可重复读的实现:
事务启动时生成一个read view ,其中包含了c_trx_id(后面简写ctrxid),m_ids,min_trx_id,max_trx_id
ctrxid是当前事务的id,mids是当前事务开启之后(还未提交)创建的事务id列表,包含当前ctrxid,mintrxid是列表中最小的trxid,maxtrxid是最大的trxid,注意这个最大应该是当前最大的+1,方便下一个事务开启时用。
例子:
事务a开启 trx_id为100,事务b也开启,trxid为101,此时a事务中mids为100和101,mintrx为a 100,maxtrxid为102,(此时b事务中mids为100和101,mintrx为a 100,maxtrxid为102)
a读取卡数据500万,此时b往里面存了100万,b提交,a第二次读还是500万
a读数据的时候发现此时卡的trxid为101,比自身大,并且比a事务中mintrxid大,此时不能读取trxid为101,往卡的历史trxid中读取,找到修改之前卡的trxid 99,此时是500万,达到了可重复读的功能。
(历史trxid,卡数据记录中有两个隐藏列,trxid和上一个记录的指针,b事务修改之后,卡的trxid为101,数据值为600万,指针索引指向记录的trxid为99,数据值为500万)

例如:
开始事务a后(begin开启)
查询部门no为1的名字为3333,
在这里插入图片描述

trxid(事务id):

在这里插入图片描述

开启新的事务b,修改no1的部门名称为zhangsan在这里插入图片描述
a事务的trxid:
在这里插入图片描述

事务b已提交:数据库查询数据已更改
在这里插入图片描述
回到事务a再次进行查询,数据还是3333,实现了可重复读的功能
在这里插入图片描述
此时a事务的trxid没有变化
在这里插入图片描述
commit后再查询,此时为zhangsan
在这里插入图片描述
再次查询事务a的trxid,此时trxid为null
在这里插入图片描述

SHOW FULL PROCESSLIST

SELECT * FROM information_schema.INNODB_TRX

UPDATE dept set dname = "1231" WHERE dept_no =2
#开启事务 分配TRX_ID
 #begin不会立即分配TRX_ID
begin;
#触发分配TRX_ID
select * from dept WHERE dept_no =1
#指定TRX_MYSQL_THREAD_ID=当前CONNECTION_ID,表示查询当前连接
select TRX_ID from INFORMATION_SCHEMA.INNODB_TRX where TRX_MYSQL_THREAD_ID = CONNECTION_ID();
commit;

当出现行锁时(当前事务未提交,同时修改同一条数据 行锁):
日志输出:
com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException: Lock wait timeout exceeded; try restarting transaction
SHOW FULL PROCESSLIST
在这里插入图片描述

SELECT * FROM information_schema.INNODB_TRX
在这里插入图片描述

CREATE TABLE `dept`  (
  `dept_no` bigint(20) NOT NULL AUTO_INCREMENT,
  `dname` varchar(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '主从数据',
  `db_source` varchar(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `time` datetime(0) DEFAULT CURRENT_TIMESTAMP,
  `deleted` tinyint(2) DEFAULT 0,
  `sex` varchar(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  PRIMARY KEY (`dept_no`) USING BTREE,
  FULLTEXT INDEX `1231`(`dname`, `sex`)
) ENGINE = InnoDB AUTO_INCREMENT = 45 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci COMMENT = '部门表' ROW_FORMAT = Compact;

mysql结合点

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值