MySql 已知条件
1、 同一个连接会话 trx_mysql_thread_id 不会变,不同事务 trx_id 不一样
2、 可重复读 通过 next-key locks 锁定
模拟场景
1 begin 开启事务后,如果没有立刻去读取A数据,
2 开启事务更新A数据并提交,1 事务这个时候去读取 A数据 将会读到 2 事务更新后的 A数据
同一会话事务超时后重新开启事务分析
跑波次运行时,如果库存被锁住,事务超时后不做回滚, 后开始调用 函数rollback 里面也会有开启事务,但是事务提交后没生效
分析
navicat模拟场景
MySql 版本 v5.6 事务隔离级别:RR
代码中事务隔离级别为RC,但实验后发现跟隔离级别无关
session 1 | session 2 |
---|---|
开启事务 | 开启事务 |
SELECT * from location_inventory where id = 272566 FOR UPDATE | 无操作 |
无操作 | update location_inventory set onHandQty =1100 where id = 272566 |
thId:275128,trxId:402631076 | thId:275633,trxId:402631085 |
无操作 | 超时50s |
无操作 | 开启事务 |
thId:275128,trxId:402631076 | INFORMATION_SCHEMA.INNODB_TRX无法查到事务 |
无操作 | update location_inventory set onHandQty =1100 where id = 272566 |
thId:275128,trxId:402631076 | thId:275633,trxId:402631961 |
从表格中可以看到begin开启事务后,再次begin会关闭上次事务,那这里就有一个疑问begin后再begin那之间修改后的数据有提交吗?
答案是可以提交更新的,begin也将触发提交事件同时开启一个新的事务。但如果上一个事务超时,这个时候再 begin 事务只是关闭而不会更新数据
从以上分析可以看出来,波次运行的问题应该是代码层面的问题,需要分析下代码中是如何开启事务。
参考:
http://blog.sae.sina.com.cn/archives/2127
https://www.cnblogs.com/wade-luffy/p/9689975.html#_label2
https://zh.wikipedia.org/wiki/%E5%A4%9A%E7%89%88%E6%9C%AC%E5%B9%B6%E5%8F%91%E6%8E%A7%E5%88%B6
http://hedengcheng.com/?p=771#_Toc374698308
如何阅读死锁日志:
https://juejin.im/post/5d483e66518825052734b15a
https://blog.csdn.net/dhfzhishi/article/details/81272360
https://www.aneasystone.com/archives/2018/04/solving-dead-locks-four.html