Thinkphp5 实现悲观锁
悲观锁介绍(百科):
悲观锁,正如其名,它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中,将数据处于锁定状态。悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,即使在本系统中实现了加锁机制,也无法保证外部系统不会修改数据)。
使用场景举例:以MySQL InnoDB为例
商品goods表,假设商品的id为2,购买数量为1,status为1表示上架中,2表示下架。现在用户购买此商品,在不是高并发的情况下处理逻辑是:
- 查找此商品的信息;
- 检查商品库存是否大于购买数量;
- 修改商品库存和销量;
上面这种场景在高并发访问的情况下很可能会出现问题。如果商品库存是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 实现悲观锁的更多相关文章
- mysql悲观锁总结和实践--转
原文地址:http://chenzhou123520.iteye.com/blog/1860954 最近学习了一下数据库的悲观锁和乐观锁,根据自己的理解和网上参考资料总结如下: 悲观锁介绍(百科): ...
- 【mysql】关于悲观锁
关于mysql中的锁 在并发环境下,有可能会出现脏读(Dirty Read).不可重复读(Unrepeatable Read). 幻读(Phantom Read).更新丢失(Lost update)等 ...
- 【MySQL】悲观锁&乐观锁
悲观锁与乐观锁是两种常见的资源并发锁设计思路,也是并发编程中一个非常基础的概念.本文将对这两种常见的锁机制在数据库数据上的实现进行比较系统的介绍. 悲观锁(Pessimistic Lock) 悲观锁的 ...
- mysql-mysql悲观锁和乐观锁
1.mysql的四种事务隔离级别 I. 对于同时运行多个事务,当这些事务访问数据库中的相同数据时,如果没有采取必要的隔离机制,就会导致各种并发问题. (1)脏读: 对于两个事物 T1, T2, T1 ...
- 【Oracle】悲观锁和乐观锁
悲观锁 如select * for update 悲观锁大多数情况下依靠数据库的锁机制实现,以保证操作最大程度的独占性.但随之而来的就是数据库性能的大量开销,特别是对长事务而言,这样 ...
- SQL-乐观锁,悲观锁之于并发
每次写博客,第一句话都是这样的:程序员很苦逼,除了会写程序,还得会写博客!当然,希望将来的一天,某位老板看到此博客,给你的程序员职工加点薪资吧!因为程序员的世界除了苦逼就是沉默.我眼中的程序员大多都不 ...
- mysql悲观锁总结和实践
使用场景举例:以MySQL InnoDB为例商品t_goods表中有一个字段status,status为1代表商品未被下单,status为2代表商品已经被下单,那么我们对某个商品下单时必须确保该商品s ...
- Oracle的悲观锁和乐观锁---摘抄
1.无论是选择悲观锁策略,还是乐观锁策略.如果一个对象被上了锁,那么该对象都会受这个锁的控制和影响.如果这个锁是个排它锁,那么其它会话都不能修改它. 2.选择悲观锁策略,还是乐观锁策略,这主要是由应用 ...
- 快钱支付与Sql Server的乐观锁和悲观锁
在实际的多用户并发访问的生产环境里边,我们经常要尽可能的保持数据的一致性.而其中最典型的例子就是我们从表里边读取数据,检查验证后对数据进行修改,然后写回到数据库中.在读取和写入的过程中,如果在多用户并 ...
随机推荐
- Python 实现 Discuz论坛附件下载权限绕过漏洞
背景:最近压力有些大,想玩点游戏放松下,去Mac论坛下载,发现需要各种权限,于是蛋疼了. 所以,上网查了discuz! x3.1破解,手动替换,发现出现“链接已过期”.所以写了下面程序. 0.将下列代 ...
- 1.Smarty的下载安装
下载地址:https://github.com/smarty-php/smarty/tree/v3.1.29 官网:smarty.net 下载解压后的目录:
- iOS开发Safari调试WebView页面
App混合开发现已是常态,不过作为app端开发人员,对H5页面的使用,可不能简单的局限于使用,一些简单的调试方法还是有必要了解的. 关于如何在使用webview过程中,如何对web内对内容进行调试,这 ...
- 读书共享 Primer Plus C-part 7
第十章 数组和指针 1.关于二维数组跟指针 #include<stdio.h> int main() { ][]={{,,,},{,,,},{,,,}}; ; ;i< ;i++) ...
- 阿里云服务器linux(cenos)下 jdk、tomcat的安装配置
一.JDK的安装与环境配置 1. 下载jdk http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-213315 ...
- 消耗CPU的程序
昨天领导交代客户需要一个可以测试CPU性能的脚本,问题简化下就是说要做一个可以手动设置对CPU产生消耗的程序.心想哪有这种脚本,或许性能测试工具还差不多.琢磨了下,或许用死循环可以达到差不多的效果,但 ...
- 什么是Hadoop
配上官方介绍 What Is Apache Hadoop? The Apache™ Hadoop® project develops open-source software for relia ...
- MySQL自动化(全量+增量)备份脚本
文章转自:http://www.it-hack.cn/forum.php?mod=viewthread&tid=220&extra=page%3D1 一.MySQL的日常备份方案: 全 ...
- JavaScript一个google地图获取
<script type="text/javascript"> /** * 返回一个新创建的<img>元素,该元素用于在获取到地理位置信息后,显示一张Goo ...
- Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals)A B题
当时晚上打CF时候比较晚,加上是集训期间的室友都没有晚上刷题的习惯,感觉这场CF很不在状态.A题写复杂WA了一发后去厕所洗了个脸冷静了下,换个简单写法,可是用cin加了ios::sync_with_s ...