300根烤羊腿引发的家庭伦理苦情剧--MySQL中的锁

本文通过一对夫妻处理税务问题的故事,生动解释了MySQL数据库中的事务和行级锁机制。在不同的情景下,展示了如何避免并发操作导致的问题,如不一致性和死锁。故事揭示了数据库事务的隔离性和锁在保护数据一致性中的关键作用,对于理解数据库管理和高性能应用开发具有重要意义。
摘要由CSDN通过智能技术生成

从前,有一对夫妻,他们琴瑟和鸣,举案齐眉,靠着不断地购买,终于积累了一笔可观的家产。

1000根烤羊腿!

    这1000根烤羊腿是丈夫和妻子分别持有的,丈夫持有800根,妻子持有200根。谁知有一天,晴空劈下来一道大雷,国家突然要以家庭为单位征收烤羊腿税了!

    以家庭为单位持有烤羊腿超过500根,就要交税啦。这可咋办啊,丈夫和妻子商量出了一个主意,俩人假离婚,丈夫再过户300根烤羊腿给妻子,这样他俩正好在500根红线上,不用交税!

    说干就干,俩人决定利用一个MySQL数据库完成300根烤羊腿的过户,他们觉得数据库能看得见,不会作弊,是最公平的。

    殊不知,他们并不了解数据库底层存储引擎的事务和锁机制,他们的命运将被底层代码安排的明明白白。

    下面,我们就从丈夫、妻子和银行三方的视角来看看这场闹剧是怎么收场的。

    首先,丈夫和妻子在银行开了户,这个户头里的一个数据表存储了他们俩分别的烤羊腿数量。他们俩和银行都查了一下,一切正常!(最左边是丈夫,中间是妻子,右边是银行

现在,我们来看看三种情况。

场景一 丈夫和妻子都是小白兔,彼此信任

    丈夫和妻子按照事先商量好的方案,同时开启了事务,目标是丈夫转出300个羊腿,妻子得到300个羊腿,俩人最终的羊腿都变成500根。

    从他俩写的代码可以看出,丈夫和妻子分别把名下的羊腿数目更新成500了,更新完后,他俩顺手查了下现在的羊腿数。

    有趣的是,丈夫和妻子此时只能看到自己所做的更新,而看不到对方的。这是由于他俩处在两个独立的事务中,没有提交事务前,彼此是看不到对方事务里所做的修改的

    不过他俩互相信任,相信对方都做出了正确的更新。

    这时候的银行呢?它看到的是什么呢?

    银行实惨,它游离于丈夫和妻子的两个独立的事务外,看不到任何一个事务内部所做的更新。在它看来,这俩人的资产还和原来一样。

    出于对彼此的信任,丈夫和妻子都敲入了代码 commit;,然后丈夫妻子和银行三方进行了一次查询。

    银行蒙了啊,这俩人啥时候完成的羊腿转移啊?丈夫和妻子则顺利完成了他们的羊腿转移。

    大胆的发散一下,其实我们通过银行给对方转账时,银行的数据库就走了一遍上述的底层逻辑。银行要的就是最后的结果没问题,至于转多少,怎么转,它不干预独立的事务。

    让我们回到羊腿转移事件上,来看看第二个场景。

场景二 丈夫心怀毒计,妻子单纯善良

    或许是想把这场假离婚坐实,或者是早就对妻子那200根烤羊腿觊觎已久,他决定使坏。

从头开始。

    丈夫和妻子同时开启了自己独立的事务,但是这次丈夫不打算履行约定了。

    从丈夫写的代码就能看出,他要完全霸占妻子的烤羊腿!而妻子显然相信丈夫,觉得他会把300个烤羊腿给自己,于是将自己的烤羊腿数量改成了500。

    接下来丈夫开始了他的计划,他直接把妻子的烤羊腿数量改成了0!

    但是,没想到的是,这次更改竟然被阻塞了!!

    是丈夫被发现了吗?不是,他在无意中触发了innodb存储引擎的行级锁

    因为妻子先他一步对属于自己的一行数据进行了修改,这时候MySQL数据库会出于对数据的保护把这行锁定,让妻子的更改没有提交事务之前无法接受别的事务内的更改

    恶毒的丈夫和善良的妻子根本不知道底层发生的这一切,妻子最终还是提交了她的更新。如果她早一点提交的话,丈夫的毒计就得逞了!

因为行级锁会随着事务的提交而被另一个事务获得并解除,另一个事务内的更新就可以运行了。

    但是现在,丈夫傻眼了。

    超时了!!善良的妻子被超时机制保护了!(其实是我的善良,我故意多拖了一会才提交了妻子的事务)丈夫的毒计没有得逞,他对妻子烤羊腿的更新被回滚了。

    无奈,他也只能提交了。现在我们再看看他俩和银行的查询。

    妻子和银行都傻眼了,妻子蒙了,我的数量是对的,丈夫怎么还多了?不过聪明的她很快想明白了,既庆幸,又绝望。

    银行怒了,你俩这是平地起了500个烤羊腿啊!作废!这笔交易作废!

    MySQL的行级锁恰如其分的保护住了妻子的利益,我们也能明白两个独立事务之间的互相更新是很容易触发行级锁的

    接下来,我们再来看看更狗血的情况。

场景三 丈夫和妻子各怀鬼胎,狗咬狗,一嘴毛

    这场突如其来的羊腿纳税风波成为了摧毁他们婚姻的最后一根稻草,丈夫和妻子各怀鬼胎,都打算霸占对方的羊腿。

好戏开始了。

    俩人和没事人一样各自开启了事务,准备大干一场了。

    因为各怀鬼胎,这俩人上来先不改自己的,先去改对方的烤羊腿数量

    看看这俩人写的代码,彼此都把对方的数量改成0,这种匪夷所思的操作真是闻所未闻。

    改完之后,丈夫先动手了!他要把自己的烤羊腿数量改成1000,妻子当然也不逞多让,她也要把自己的烤羊腿数量改成1000!

    这时候,有意思了!死锁了!

    为什么会死锁?这俩人咎由自取,原来丈夫改了妻子的数据,在丈夫的事务里妻子的数据被加了个行级锁,同理妻子的事务里丈夫的数据也被加了个行级锁。他俩再分别改自己的数据的时候,锁都在对方手里,既提交不了,又拿不到锁,所以就死锁啦!

    他俩根本不知道这背后的逻辑,竹篮打水一场空,互相算计,两败俱伤。

    这便是MySQL的innodb引擎中行级锁的死锁情况,互相争夺资源,互相锁死。

    通过这对夫妻的故事,我们也很好的理解了MySQL数据库中事务和锁的运行机制,这对我们开发高性能高并发的MySQL数据库是很有意义的

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值