for update什么时候释放锁_mysql中的悲观锁与乐观锁的实现

a.悲观锁的特点是先获取锁,再进行业务操作,即悲观的认为所有的操作均会导致并发安全问题,因此要先确保获取锁成功再进行业务操作。通常来讲,在数据库上的悲观锁需要数据库本身提供支持,即通过常用的select ... for update操作来实现悲观锁,当数据库执行select ... for update时会获取被select中的数据行的行锁,因此其他并发执行的slect ... for update如果视图选中同一行则会发生排斥,需要等待行锁被释放,因此达到锁的效果。select ... for update获取的行锁会在当前事务结束时自动释放,因此必须在事务中使用。这里需要特别注意的是,不同的数据库对select ... for update的实现和支持都是有所区别的,例如oracle支持select for update no wait,表示如果拿不到锁立刻报错,而不是等待,mysql就没有no wait这个选项,另外mysql还有个问题是select ... for update语句执行中所有扫描过的行都会被锁上,这一点很容易造成问题,因此如果在mysql中用悲观锁务必要确定使用索引,而不是全表扫描。

b.乐观锁的特点先进行业务操作,只在最后实际更新数据时进行检查数据是否被更新过,若为被更新过,则更新成功,否则失败重试。乐观锁是否在事务中其实都是无所谓的,其底层机制是这样:在数据库内部update同一行的时候是不允许并发的,即数据库每次执行一条update语句时会获取被update行的写锁,直到这一行被成功更新后才释放。因此在业务操作进行前获取需要锁的数据的当前版本号,然后实际更新数据时再次对比版本号确认与之前获取的相同,并更新版本号,即可确认这期间没有发生并发的修改。如果更新失败,即可认为老版本的数据已经被并发修改而不存在了,此时认为获取锁失败需要回滚整个业务操作并可根据需要重试整个过程。

c.悲观锁与乐观锁的应用场景

一般情况下,读多写少更适合用乐观锁,读少写多更适合用悲观锁,乐观锁在不发生取锁失败的情况下开销比悲观锁小,但是一旦发生失败回滚则开销则比较大,因此适合用在取锁失败概率比较小的场景,可以提升系统并发性能。

e134e456d54e18b66fa73b49bc035d2b.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值