mysql select for_MySQL数据库select for update探究

针对select for update的原理,在网络上有很多文章都有讲过,具体的用法也有文章进行讲解,其中也不乏一些优秀的文章。但是针对于具体的使用中的表现并没有太多。

本篇博客以select for update与update的执行表现为例,记录实际使用过程中的心得。本篇不讲原理,只讲表现。

阅读必知使用sql命令窗口一,执行select for update,关闭事务的自动提交,模拟在系统中开启了事务,以下简称“事务一”。

使用sql命令窗口二,执行update,同样关闭事务的自动提交,模拟在系统中开启了事务。update的操作也可以是事务自动提交的,但是为了更清楚的描述发生了什么,所以也关闭了事务的自动提交,以下简称“事务二”。

事务级别:RR——可重复读。

测试过程

第一种情况,select for update执行在“update与update的commit”之间查看数据的当前状态,使用事务一或事务二均可 ↓

93eb7435bdbbedaaa7058d6f796731d7.png

事务一,关闭事务的自动提交 ↓

78791b4d70dd84f759aa7a3527bc60bb.png

事务二,关闭事务的自动提交 ↓

78791b4d70dd84f759aa7a3527bc60bb.png

事务二,执行update,将status值修改为10 ↓

946561d5624d63b3135e1790b4af7ee5.png 可以看到,此时update语句是可以正常执行的,但此时事务二是未提交的。

事务一,执行select,查询当前的status值 ↓

c1fd7cac986d41734adcc5d860ef2414.png 因为事务二还未提交,所以此时可以看到事务一查询到的status的旧值。

事务一,执行select for update,查询当前的status值 ↓

9f0338e9029a343516287484b4eb5b2f.png 因为事务二,还未提交,所以事务一中执行的select for update是被阻塞的,并没有打印查询结果。

事务二,执行commit,将修改提交 ↓

5f3b622ce706cbd39683ec04c439da9d.png 此时去看事务一的窗口,发现select for update的结果已经正常打印出来,且status的值为update修改的值。

4b235cff726364258cf00d819d67fe49.png

情况一总结:select for update执行在“update与update的commit”之间时,update的事务在未提交之前,会阻塞select for update的执行,只有update的事务提交之后,select for update才能正常返回结果。

情况二,update执行在“select for udpate与select for update的commit”之间查看数据的当前状态,使用事务一或事务二均可 ↓

93eb7435bdbbedaaa7058d6f796731d7.png

事务一,关闭事务的自动提交 ↓

78791b4d70dd84f759aa7a3527bc60bb.png

事务二,关闭事务的自动提交 ↓

78791b4d70dd84f759aa7a3527bc60bb.png

事务一,执行select for update,但未commit ↓

cdf3963c91e9ff5fec8d77d55414622a.png 结果可以正常返回,但此时已经开启了一个锁,锁定了数据。

事务二,执行update,修改status的值为10 ↓

4dad62c79f9fdd18d25be3a6cd1e85e9.png 因为事务一没有提交,所以事务一持有锁,事务二的update会被阻塞。

事务一,执行commit ↓

fdac14588403071a97fce0951668736c.png 事务一执行commit,此时可以看到事务二的阻塞被解除,修改生效,但此时的update依旧是未commit的 ↓

c8ce46ed114a416e776528f95a1afc80.png

事务一,执行select,读取到status的旧值:100 ↓

eb401ab01a7ce6d9457f19a8dd97a320.png 因为事务一没有commit,所以select查询到的是旧值,即status=100。若此时执行select for update,则进入到了情况一所描述的情况,在此不再展开。

事务二,执行commit ↓

97b77805253193025fc4f8cc3b09e78f.png

事务一,再次执行select,读到status的值:100 ↓

ca9d51f1ddfbd36cc581b5e5e91f31ed.png 因为数据库的事务级别是RR的,所以这个地方读取到的还是100。

事务一,执行一次commit后再执行select,读取status的新值:10 ↓

fd05f54cb3a0053e88e275273006efec.png

情况二总结:update执行在“select for update与select for update的commit”之间时,select for update的事务在未提交之前,会阻塞update的执行,只有select for update的事务提交之后,update才能正常返回结果。

总结:select for update执行的是当前读。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值