作者回复: 你的问题被引用最多,我回复你哈,其它同学看过来😄
好吧,今天的课后问题其实比较简单,本来是隐藏在思考题里的彩蛋,被你问出来了哈。
Innodb 要保证这个规则:事务启动以前所有还没提交的事务,它都不可见。
但是只存一个已经提交事务的最大值是不够的。 因为存在一个问题,那些比最大值小的事务,之后也可能更新(就是你说的98这个事务)
所以事务启动的时候还要保存“现在正在执行的所有事物ID列表”,如果一个row trx_id在这列表中,也要不可见。
虽然踩破了彩蛋,还是赞你的思考哈,置顶让大家学习😄
作者回复: 早
赞
置顶了
明天课后问题时间直接指针引用了哈😄
补充一下:上面说的“如果失败就重新起一个事务”,里面判断是否成功的标准是 affected_rows 是不是等于预期值。
比如我们这个例子里面预期值本来是4,当然实际业务中这种语句一般是匹配唯一主键,所以预期住值一般是1。
作者回复: 你这个问题很有趣。我想到一个不错的解法。不过我先置顶。让别的同学来回答看看。
好问题,谁有想法po出来。
作者回复: 好问题,有很深入的思考哈
代码实现上,获取视图数组和高水位是在事务系统的锁保护下做的,可以认为是原子操作,期间不能创建事务。
作者回复: 👍🏿
我在学习过程中也是最喜欢这种“自己推翻自己结论”的快感
作者回复: 1. 判断可见性两个规则:一个是up_limit_id ,另一个是“自己修改的”;这里用到第二个规则
2. 这时候事务Bup_limit_id还是99
作者回复: 咱们例子里面,事务C是直接提交的,再执行一个GET 就是另外一个事务了…
如果你说的是用begin 来启动一个多语句事务,那么事务c在更新后查询,还是看到row trx_id是102的。 【注意:如果它还没提交,101根本生成不出来,因为事务B被行锁挡着呢】
作者回复: 👍🏿
本篇知识点全get
作者回复: 嗯嗯,分析得很对。
茅塞顿开的感觉很好,恭喜🎉🎈
作者回复: 赞👍🏿
慢慢来
作者回复: 谢谢你,我倍受鼓舞呀😄
作者回复: 你设计一个“比低水位大,但是在当前事务启动前,就已经提交了的例子😄
作者回复: 这是个好问题,也是并发业务常见的问题。
一开始Select 加锁虽然可以,但是会比较严重地影响并发数。
比较简单的做法是update语句的where 部分加一个条件: where nun >=200 .
然后在程序里判断这个update 语句的affected_rows,
如果等于1 那就是符合预期;
如果等于0,那表示库存不够减了,业务要处理一下去,比如提示“库存不足”
作者回复: 在这版里面就是用“低水位”来作为活跃的最小ID的概念,
嗯其实是为了理解原理,用了不同的表述方式哈。
后面发现上一版的描述方法太公式化了,不利于人工分析
作者回复: 👍
这个跟我文章的方案是不是差不多的?
不过把字段名改成 less_userid 和 greater_userid,确实更好理解了哦。
新春快乐~
作者回复: 那就是没复现😄
作者回复: 赞,这个想通的感觉是很爽的
作者回复: 比低水位大的不一定已经提交了哦
比如一个事务启动时当前活跃事务是[99,100,102], 而101已经提交了
作者回复: 厉害了。。~