这篇文章主要介绍“Innodb锁定读是什么”,在日常操作中,相信很多人在Innodb锁定读是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Innodb锁定读是什么”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
如果查询数据,接着在相同的事务中插入或者修改相关数据,常规的select语句不能保护数据不被其他事务修改。其他事务可以更新或者删除刚才查询事务中相同的行。
InnoDB支持2种类型的锁定读:
1、SELECT … LOCK IN SHARE MODE设置一个共享S锁在被查询的行上。其他会话能读取这些行,但是不能修改相应行的数据,直到此事务结束。如果其他事务对相应的行进行了DML操作,而未结束事务前,那当前事务中进行SELECT … LOCK IN SHARE MODE将一直等待,直到另外的事务完成。
2、SELECT … FOR UPDATE设置一个排他X锁在相应的行上。按照索引进行select for update查询时,会锁住相关的索引条目和行数据。同样的,此期间其他事务对相关的行进行更新、SELECT … LOCK IN SHARE MODE、在某些事务隔离级别读数据都将会被堵塞,但一致性读会忽略存在的任何锁,因为老版本的数据不能被锁定,它们通过undo log在内存中构造数据的拷贝。
注意:使用锁定读操作的时候,必须开启事务(可以通过START TRANSACTION或者set autocommit=0来开启事务),锁定读相关的锁在事务commit或者rollback时,都会立即释放。如果没有开启事务,则相关的行不会被锁定。
用法举例
假如要往子表插入一条记录,插入前首先要确认一下父表有无相关记录,只有在父表有对应记录时插入才能满足应用数据的完整性约束。如果使用一致性非锁定读来检查父表相应的记录,而在往子表插入对应数据的瞬间,其他会话的事务刚好在你查询父表之后插入子表之前删除或者修改了刚才查到的行,这样接下来的插入操作将可能会不能顺利的完成。
可以使用LOCK IN SHARE MODE进行锁定读,来避免此潜在的问题。如下:
SELECT * FROM parent WHERE NAME = 'Jones' LOCK IN SHARE MODE;
在父表使用LOCK IN SHARE MODE进行查询到jones,此时你能安全的在子表中插入jones相关的数据。此期间如果有其他会话事务视图DML父表中相应的行将会被阻塞,直到你的完成你的操作后结束锁定读的事务,这样可以保证父表、子表的数据的一致性。
另外一个场景,如有两个session需要读取某表A中的一行,在成功读取后在同一事务中更新该行,并在另外的表B中插入刚开始读取到的行。若此时使用SELECT…LOCK IN SHARE MODE则会对读取到A表的记录加S锁,两个session在同时申请X锁进行更新时便发生死锁。另外,由于读取到了A表同一行内容,两个session在向同一表B插入数据时会导致键重复的错误。这种情况下用LOCK IN SHARE MODE不是好的办法,而使用SELECT…FOR UPDATE较合适,在读取的时候阻塞其他事物的读和更新请求。
到此,关于“Innodb锁定读是什么”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!
原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/202413.html