去年十月份还是十一月左右,第一次接触到for update,当时有个异常场景,开发同事说可以锁读记录实现,select查询语句后面加上for update就行。
对于我测试来说,使用锁读大致的操作过程就是:
①选择手动提交事务;②执行select…for update语句;③处理完成后提交事务。
当时只是粗略的了解了一下是个行级锁,锁住了就不能做修改,初体验转瞬即逝就没有放在心上。最近因为测试异常,频繁的使用到,所以就很好奇这到底是个什么原理。
看了一些视频和讲解,大概浅显的捋一捋
1.for update实际是一个悲观锁,具有排他性和独占性,取数时默认其他操作每次都会修改数据,所以为了保证数据访问的排他性,在取数的同时会一直让数据处在锁定状态,这样别的操作过来就会阻塞或者回滚,等锁释放后再次尝试获取锁,在实际的应用中主要是解决多线程篡改共享数据的问题(或者其他?)。
2.for update是锁表还是锁行?如果是用到了索引去查数据,那么是行级锁,如果未使用到索引,应当是表级锁。
3.假设事务1进行了for update操作,那么其他记录是否能进行锁读或者读操作呢?看到了两种解释如下所示。
解释一:
(1)事务1对某个数据date进行for update操作,此时事务1既可以对date进行读也可以进行写,倘若其他事物也想做for update操作,那就只会失败。
(2)事务1对对某个数据date进行for update操作,倘若其他事物只去select,那么是可以读到的。
解释二,(涉及到排它锁与共享锁):
(1)排它锁(X锁,Exclusive Lock),如果事务1获取的是数据date的排它锁,那么事务1对date可读可写,但是在事务1释放X锁之前,其他事物即不能获取S锁也不能获取X锁,也就是不可读也不可写。
(2)共享锁(S锁,Shared Lock),如果事务1获取的是数据date的共享锁,那么事务1对date可读可写,但是在事务1释放X锁之前,其他事物只能获取到S锁,也就是能读date,而不能修改date,与此同时也并不能对date加上X锁,直到事务1将S锁释放。
总的概括一下,也就是,事务1加锁,事务2就不能再加锁,必须要等锁资源释放,但如果事务2不加锁,那么不会限制他去查询数据,但是肯定不会允许修改数据。
(PS:锁记录的同时去删除该条记录,这样应该也算是修改了数据?上述内容如果有错误的地方烦请有缘人指正下,也好更好的学习)