悲观锁介绍(百科):

悲观锁,正如其名,它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中,将数据处于锁定状态。悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,即使在本系统中实现了加锁机制,也无法保证外部系统不会修改数据)。


使用场景举例:以MySQL InnoDB为例

商品goods表,假设商品的id为2,购买数量为1,status为1表示上架中,2表示下架。现在用户购买此商品,在不是高并发的情况下处理逻辑是:

  1. 查找此商品的信息;
  2. 检查商品库存是否大于购买数量;
  3. 修改商品库存和销量;

上面这种场景在高并发访问的情况下很可能会出现问题。如果商品库存是100个,高并发的情况下可能会有1000个同时访问,在到达第2步的时候,都会检测通过。这样会出现商品库存是-900个的情况。显然着不满足需求!!!

使用悲观锁在处理。

当我们在查询出goods信息后就把当前的数据锁定,直到我们修改完毕后再解锁。那么在这个过程中,因为goods被锁定了,就不会出现有第三者来对其进行修改了。

注:要使用悲观锁,我们必须关闭mysql数据库的自动提交属性,因为MySQL默认使用autocommit模式,也就是说,当你执行一个更新操作后,MySQL会立刻将结果进行提交。

 /**
* thinkphp使用悲观锁。悲观锁需要配合事务一起使用
* 商品表。购买数量为1,先锁定该商品,不让其他操作减库存。
*/
public function mysql_lock(){
$num = 1;
$goods_id = 2;
$model = \db('goods');
$model->execute('set autocommit=0');
$model->startTrans();
//使用主键或者其他索引字段时为行级锁,否则为表级锁
$where['id'] = $goods_id;
$where['status'] = 1;
$goods_info = $model->lock(true)->where($where)->find();
if(empty($goods_info)){
return '商品不存在';
}
$total = $goods_info['total']; //商品库存
$sell = $goods_info['sell']; //商品销量
if($total<$num){
return '库存不足';
}
$data['total'] = $total-$num;
$data['sell'] = $sell+$num;
$res = $model->where(array('id'=>$goods_id))->update($data);
if($res){
$order_model = \db('orders');
$order_data['uid'] = rand(1000,9999);
$order_data['status'] = 1;
$order_data['create_time'] = date('Y-m-d H:i:s');
$order_res = $order_model->insert($order_data);
if($order_res){
$model->commit();
}else{
$model->rollback();
}
}else{
$model->rollback();
}
exit; } /**
* 不加锁的情况
* @return string
*/
public function mysql_unlock(){
$num = 1;
$goods_id = 2;
$model = \db('goods');
$model->execute('set autocommit=0');
$model->startTrans();
$where['id'] = $goods_id;
$where['status'] = 1;
$goods_info = $model->where($where)->find();
if(empty($goods_info)){
return '商品不存在';
}
$total = $goods_info['total']; //商品库存
$sell = $goods_info['sell']; //商品销量
if($total<$num){
return '库存不足';
}
$data['total'] = $total-$num;
$data['sell'] = $sell+$num;
$res = $model->where(array('id'=>$goods_id))->update($data);
if($res){
$order_model = \db('orders');
$order_data['uid'] = rand(1000,9999);
$order_data['status'] = 1;
$order_data['create_time'] = date('Y-m-d H:i:s');
$order_res = $order_model->insert($order_data);
if($order_res){
$model->commit();
}else{
$model->rollback();
}
}else{
$model->rollback();
}
exit; }

加锁和不加锁的测试请看下篇文章【Thinkphp5 用ab压力测试工具测试高并发请求】。

Thinkphp5 实现悲观锁的更多相关文章

  1. mysql悲观锁总结和实践--转

    原文地址:http://chenzhou123520.iteye.com/blog/1860954 最近学习了一下数据库的悲观锁和乐观锁,根据自己的理解和网上参考资料总结如下: 悲观锁介绍(百科): ...

  2. 【mysql】关于悲观锁

    关于mysql中的锁 在并发环境下,有可能会出现脏读(Dirty Read).不可重复读(Unrepeatable Read). 幻读(Phantom Read).更新丢失(Lost update)等 ...

  3. 【MySQL】悲观锁&乐观锁

    悲观锁与乐观锁是两种常见的资源并发锁设计思路,也是并发编程中一个非常基础的概念.本文将对这两种常见的锁机制在数据库数据上的实现进行比较系统的介绍. 悲观锁(Pessimistic Lock) 悲观锁的 ...

  4. mysql-mysql悲观锁和乐观锁

    1.mysql的四种事务隔离级别 I. 对于同时运行多个事务,当这些事务访问数据库中的相同数据时,如果没有采取必要的隔离机制,就会导致各种并发问题. (1)脏读: 对于两个事物 T1, T2, T1 ...

  5. 【Oracle】悲观锁和乐观锁

    悲观锁     如select * for update     悲观锁大多数情况下依靠数据库的锁机制实现,以保证操作最大程度的独占性.但随之而来的就是数据库性能的大量开销,特别是对长事务而言,这样  ...

  6. SQL-乐观锁,悲观锁之于并发

    每次写博客,第一句话都是这样的:程序员很苦逼,除了会写程序,还得会写博客!当然,希望将来的一天,某位老板看到此博客,给你的程序员职工加点薪资吧!因为程序员的世界除了苦逼就是沉默.我眼中的程序员大多都不 ...

  7. mysql悲观锁总结和实践

    使用场景举例:以MySQL InnoDB为例商品t_goods表中有一个字段status,status为1代表商品未被下单,status为2代表商品已经被下单,那么我们对某个商品下单时必须确保该商品s ...

  8. Oracle的悲观锁和乐观锁---摘抄

    1.无论是选择悲观锁策略,还是乐观锁策略.如果一个对象被上了锁,那么该对象都会受这个锁的控制和影响.如果这个锁是个排它锁,那么其它会话都不能修改它. 2.选择悲观锁策略,还是乐观锁策略,这主要是由应用 ...

  9. 快钱支付与Sql Server的乐观锁和悲观锁

    在实际的多用户并发访问的生产环境里边,我们经常要尽可能的保持数据的一致性.而其中最典型的例子就是我们从表里边读取数据,检查验证后对数据进行修改,然后写回到数据库中.在读取和写入的过程中,如果在多用户并 ...

随机推荐

  1. angular.js ng-repeat渲染时出现闪烁问题解决

    当我们前端运用到angular.js框架时,想必大家都会遇到一些坑.其中,我也来分享一个常见的angular.js渲染时出现的坑. 当我们进行页面渲染时,绑定表达式最开始会用{{data.name}} ...

  2. Threejs 开发3D地图实践总结

    前段时间连续上了一个月班,加班加点完成了一个3D攻坚项目.也算是由传统web转型到webgl图形学开发中,坑不少,做了一下总结分享. 1.法向量问题 法线是垂直于我们想要照亮的物体表面的向量.法线代表 ...

  3. python编程快速上手之第9章实践项目参考答案

    本章介介绍了shutil,zipfile模块的使用,我们先来认识一下这2个模块吧. 一.shutil模块 shutil模块主要用于对文件或文件夹进行处理,包括:复制,移动,改名和删除文件,在shuti ...

  4. P2286 [HNOI2004]宠物收养场

    题目描述 凡凡开了一间宠物收养场.收养场提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物. 每个领养者都希望领养到自己满意的宠物,凡凡根据领养者的要求通过他自己发明的一个特殊的公式,得出该领 ...

  5. Struts2+Spring+Hibernate+Jbpm技术实现Oa(Office Automation)办公系统第一天框架搭建

    =============编码规范,所有文健,所有页面,所有数据库的数据表都采用UTF-8编码格式,避免乱码:===========开发环境:jdk1.7+tomcat8.0+mysql5.7+ecl ...

  6. gulp-rev-append静态资源添加版本号后缀,清理缓存

    大多用的是gulp-rev.gulp-rev-collerctor两个插件,但过程有点麻烦,使用gulp-rev-append插件轻松搞定 github:   https://github.com/b ...

  7. 输入3个数a,b,c,按大小顺序输出

    题目:输入3个数a,b,c,按大小顺序输出 package com.li.FiftyAlgorthm; import java.util.Scanner; /** * 题目:输入3个数a,b,c,按大 ...

  8. vim的tab键设定

    多在windows上编程的童鞋可能习惯于感受tab键为4个空格的长度,不过在linux系统中一般默认设定tab键为8个空格长度来显示.事实上tab也确实是8个空格的长度.不过由于习惯问题,某些童鞋还是 ...

  9. Android自动问题——黑屏、死机等解决方法

    今天用了下Android Studio,出现了一些问题,现在将启动过程中遇到的问题和解决方案列出来,方便大家参考. 安装过程不多说,网上一搜一大把. 那直接说问题吧: 1. 无法启动,报错:Faile ...

  10. Multimodal —— 看图说话(Image Caption)任务的论文笔记(三)引入视觉哨兵的自适应attention机制

    在此前的两篇博客中所介绍的两个论文,分别介绍了encoder-decoder框架以及引入attention之后在Image Caption任务上的应用. 这篇博客所介绍的文章所考虑的是生成captio ...