当前位置: 首页 > 后端技术 > Java

面试官问我一条update语句加了多少锁?我总结了全套八字随笔

时间:2023-04-01 14:58:32 Java

题目:面试官问我一条updat语句加了多少锁?我总结了整套千篇一律的作文,你的面试官就来找你了,一个穿着格子衬衫,啤酒肚,发际线严重后退的中年男人。手里拿着泡了枸杞子的保温杯,胳膊下夹着一台MacBook,MacBook上贴着公司标语:“我爱加班”。采访开始,开门见山。面试官:简历上说你精通MySQL。我问你一个关于MySQL锁的问题。你能看出哪些数据会被这条SQL锁定吗?updateusersetname='Yideng'whereage=5;表结构如下:CREATETABLE`user`(`id`intNOTNULLAUTO_INCREMENTCOMMENT'primarykey',`name`varchar(255)DEFAULTNULLCOMMENT'name',`age`intDEFAULTNULLCOMMENT'age',PRIMARYKEY(`id`),KEY`idx_age`(`age`))ENGINE=InnoDBCOMMENT='usertable';I:age是一个非唯一索引,MySQL给索引加了锁,应该只锁age=10的数据。采访者:你确定吗?我:嗯……应该是吧。面试官:[挖苦],这就是你对MySQL的熟练程度?今天过来面试,等有消息我再联系你。后面有消息吗?你什么时候主动联系我的?说真话的被拒,背八股的作文溜走的被录取了。好吧,等我看一登如何总结MySQL八字随笔。我:这个SQL锁定什么数据,要看表里有什么数据。MySQL有三种行锁:记录锁(RecordLocks):即锁定某条记录。#锁定id=1的用户updateusersetage=age+1whereid=1;间隙锁(GapLocks):即锁定一定范围,但不包含该范围的关键数据。#锁定id大于1小于10的用户updateusersetage=age+1whereid>1andid<10;上述SQL的锁定范围是(1,10)。Next-KeyLocks:由记录锁和间隙锁组成,既包括记录本身,也包括范围,左开右闭区间。#锁定id大于1小于等于10的用户updateusersetage=age+1whereid>1andid<=10;如果表中只有两个数据:idnameage1张三110李四10为年龄索引,很容易生成这样三个索引范围:(-∞,1],(1,10],(10,+∞)就这条SQL:updateusersetname='Yileng'whereage=5;因为表中没有age=5的记录,而age=5刚好在(1,10]范围内,所以范围(1,10]会被锁定,我们可以用实际数据来测试一下:当我们执行update语句的时候,age=2和age=8的数据范围被锁定了。面试官:小伙子回答的不错。如果age=5的数据已经存在了,刚才的update语句会影响哪些数据?加锁?我:如果表中的数据是这样的idnameage1zhangsan151lamparchitecture510lisi10对于age索引,四个索引范围生成:(-∞,1],(1,5],(5,10],(10,+∞)刚才的SQL:updateusersetname='Yileng'whereage=5;age的数据=5落在(1,5)的范围内,所以会Lock(1,5)的范围。你以为这样就结束了吗?为了保证数据安全,MySQL锁会向右遍历,直到条件不满足,会加一个间隙锁,即(5,10]range.所以,这条SQL返回的锁是(1,5]和(5,10)。和刚才age=5时不存在的锁范围(1,10]是一样的,不信.再用刚才的测试用例跑一遍面试官:有点小男孩,如果我把sql中的where条件换成主键ID,锁的范围是多少?updateusersetname='Yileng'whereid=5;我:因为在索引上加了锁,如果没有id=5的数据,加锁范围和前面的SQL一样,(1,10)。如果有id=5的数据,MySQL的Next-KeyLocks会退化为RecordLocks,即只锁定id=5的行。面试官:年轻人,升职加薪的机会是留给你这样的人的。工资翻倍,明天来上班。知识点总结:MySQL锁是加在索引记录上的。如果是非唯一索引,不管记录在表中是否存在,除了对记录所在的范围进行锁定外,还会向右遍历,对不满足条件的范围进行锁定.如果是唯一索引,如果记录存在于表中,则只锁定行记录。如果该记录在表中不存在,除了对该记录所在的范围进行锁定外,还会向右遍历,对不满足条件的范围进行锁定。文章持续更新中,大家可以在微信搜索“一光架构”第一时间阅读更多技术干货。