laravel 中悲观锁 & 乐观锁的使用
关键词: 发布时间:2018-06-21 14:05:46 浏览次数:571

悲观锁 & 乐观锁

悲观锁(Pessimistic Lock),顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁、表锁、读锁、写锁等,都是在做操作之前先上锁。

乐观锁(Optimistic Lock),顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制实现。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库如果提供类似于 write_condition 机制的其实都是提供的乐观锁。

下面我们看下悲观锁和乐观锁在 Laravel 中的使用:

悲观锁使用

Laravel 查询构建器提供了一些方法帮助你在 select 语句中实现“悲观锁”。可以在查询中使用 sharedLock 方法从而在运行语句时带一把”共享锁“。共享锁可以避免被选择的行被修改直到事务提交:

DB::table('users')->where('votes', '>', 100)->sharedLock()->get();

上面这个查询等价于下面这条 SQL 语句:

select * from `users` where `votes` > '100' lock in share mode

此外你还可以使用 lockForUpdate 方法。“for update”锁避免选择行被其它共享锁修改或删除:

DB::table('users')->where('votes', '>', 100)->lockForUpdate()->get();

上面这个查询等价于下面这条 SQL 语句:

select * from `users` where `votes` > '100' for update

for update 与 lock in share mode 都是用于确保被选中的记录值不能被其它事务更新(上锁),两者的区别在于 lock in share mode 不会阻塞其它事务读取被锁定行记录的值,而 for update 会阻塞其他锁定性读对锁定行的读取(非锁定性读仍然可以读取这些记录,lock in share mode 和 for update 都是锁定性读)。

这么说比较抽象,我们举个计数器的例子:在一条语句中读取一个值,然后在另一条语句中更新这个值。使用 lock in share mode 的话可以允许两个事务读取相同的初始化值,所以执行两个事务之后最终计数器的值+1;而如果使用 for update 的话,会锁定第二个事务对记录值的读取直到第一个事务执行完成,这样计数器的最终结果就是+2了。

乐观锁使用

乐观锁,大多是基于数据版本 ( Version )记录机制实现。何谓数据版本?即为数据增加一个版本标识,在基于数据库表的版本解决方案中,一般是通过为数据库表增加一个 “version” 字段来实现。

读取出数据时,将此版本号一同读出,之后更新时,对此版本号加一。此时,将提交数据的版本数据与数据库表对应记录的当前版本信息进行比对,如果提交的数据版本号大于数据库表当前版本号,则予以更新,否则认为是过期数据。

总结

两种锁各有优缺点,不可认为一种好于另一种,像乐观锁适用于写比较少的情况下,即冲突真的很少发生的时候,这样可以省去了锁的开销,加大了系统的整个吞吐量。但如果经常产生冲突,上层应用会不断的进行重试,这样反倒是降低了性能,所以这种情况下用悲观锁就比较合适。


赞:(20)
踩:(0)
相关文章
laravel整合dingo/api方法步骤:jwt
laravel页面静态化的方法
一个简单的laravel分表联合查询
laravel对具体的路由不采用csrfTok
laravel学习笔记
laravel监听sql并生成日志,php art
laravel faker生成测试数据
laravel日期-carbon
laravel 模板中字符截断
laravel不转义富文本中html标签
热门文章
win7中将文件拷贝到虚拟机linux下
php中用uploadify上传时session丢
laravel页面静态化的方法
centos7.4 64位下swoole安装及配置
centos7.4下php7.25多线程pthreads
微信扫一扫在哪
php-fpm经常卡死
单点登录sso原理及php实现方式及de
phpexcel设置行高及列宽,背景颜色,
一个简单的laravel分表联合查询
好评文章
php7中使用mongodb的aggregate进行
windows下使用MongoDB Compass Com
phpexcel设置行高及列宽,背景颜色,
laravel 中悲观锁 & 乐观锁的使用
laravel整合dingo/api方法步骤:jwt
在php中用curl请求java接口无法获
laravel页面静态化的方法
一个简单的laravel分表联合查询
laravel对具体的路由不采用csrfTok
php7 mongodb distinct及count方法
标签
rabbitmq mysql备份 elasticsearch
站点信息
建站时间:2011年
文章数:500篇
浏览数:253628
粤ICP备18028092号-1  微信:hurong241