对于商品抢购等并发场景下,可能会出现超卖的现象,这时就需要解决并发所带来的这些问题了

在PHP语言中并没有原生的提供并发的解决方案,因此就需要借助其他方式来实现并发控制。

方案一:使用文件锁排它锁

flock函数用于获取文件的锁,这个锁同时只能被一个线程获取到,其它没有获取到锁的线程要么阻塞,要么获取失败

在获取到锁的时候,先查询库存,如果库存大于0,则进行下订单操作,减库存,然后释放锁

方案二:使用MySQL数据库提供的悲观锁

Innodb存储引擎支持行级锁,当某行数据被锁定时,其他进程不能对这行数据进行操作

先查询并锁定行:select stock_num from table where id=1 for update

if(stock_num > 0){

//下订单

update table set stock_num=stock-1 where id=1

}

方案三:使用队列

将用户的下单请求依次存入一个队列中,后台用一个单独的进程处理队列中的下单请求

方案四:使用Redis

redis的操作都是原子性的,可以将商品的库存存入redis中,下单之前对库存进行decr操作,如果返回的值大于等于0等可以下单,否则不能下单,这种方式效率较高

if(redis->get('stock_num') > 0){

stock_num = redis->decr('stock_num')

if(stock_num >= 0){

//下订单

}else{

//库存不足

}

}else{

//库存不足

}

其他并发问题:

在现实应用中,很多情况下会把数据存入缓存,当缓存失效时,去数据库取数据并重新设置缓存,如果这时并发量很大,会有很多进程同时去数据库取数据,导致很多请求

穿透到数据库,而使数据库奔溃,这里可用文件锁来解决

 1     $data = $cache->get('key');
2 if(!$data){
3 $fp = fopen('lockfile');
4 if(flock($fp, LOCK_EX)){
5 $data = $cache->get('key');//拿到锁后再次检查缓存,这时可能已经有了
6 if(!$data){
7 $data = mysql->query();
8 $cache->set('key', $data);
9 }
10 flock($fp, LOCK_UN);
11 }
12 fclose($fp);
13 }

说白了,要解决并发问题就必须要加锁,各种方案的本质都是加锁

 
 
 

PHP解决并发问题的几种实现(转)的更多相关文章

  1. PHP解决并发问题的几种实现

    对于商品抢购等并发场景下,可能会出现超卖的现象,这时就需要解决并发所带来的这些问题了 在PHP语言中并没有原生的提供并发的解决方案,因此就需要借助其他方式来实现并发控制. 方案一:使用文件锁排它锁 f ...

  2. EntityFramework Core解决并发详解

    前言 对过年已经无感,不过还是有很多闲暇时间来学学东西,这一点是极好的,好了,本节我们来讲讲EntityFramewoek Core中的并发问题. 话题(EntityFramework Core并发) ...

  3. 构建高性能服务(二)java高并发锁的3种实现

    构建高性能服务(二)java高并发锁的3种实现 来源:http://www.xymyeah.com/?p=46   提高系统并发吞吐能力是构建高性能服务的重点和难点.通常review代码时看到sync ...

  4. hibernate 解决并发问题

    hibernate 解决并发问题的策略有 1)设置hibernate事务隔离级别 2)hibernate中乐观锁的实现 ps:版本号是由hibernate自己维护的,我们自己只需要做以上二步即可实现乐 ...

  5. ThreadLocal可以解决并发问题吗?

    前言 到底什么是线程的不安全?为什么会存在线程的不安全?线程的不安全其实就是多个线程并发的去操作同一共享变量没用做同步所产生意料之外的结果.那是如何体现出来的呢?我们看下面的一个非常经典的例子:两个操 ...

  6. 【漫画】CAS原理分析!无锁原子类也能解决并发问题!

    本文来源于微信公众号[胖滚猪学编程].转载请注明出处 在漫画并发编程系统博文中,我们讲了N篇关于锁的知识,确实,锁是解决并发问题的万能钥匙,可是并发问题只有锁能解决吗?今天要出场一个大BOSS:CAS ...

  7. 数据库事务 ACID属性、数据库并发问题和四种隔离级别

    数据库事务 ACID属性.数据库并发问题和四种隔离级别 数据库事务 数据库事务是一组逻辑操作单元,使数据从一种状态变换到另一种状态 一组逻辑操作单元:一个或多个DML操作 事务处理原则 保证所有事务都 ...

  8. 使用mysql悲观锁解决并发问题

    最近学习了一下数据库的悲观锁和乐观锁,根据自己的理解和网上参考资料总结如下: 悲观锁介绍(百科): 悲观锁,正如其名,它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持 ...

  9. list的迭代器能解决并发问题,collection 的迭代器不能解决并发问题,for可以解决并发问题

    list的迭代器能解决并发问题,collection 的迭代器不能解决并发问题 为什么list支持add,collection不支持 例如有两个人同时添加第三个元素 list的迭代器能锁定线程 只有等 ...

随机推荐

  1. CAD中解决打印图纸模糊而且有的字体深浅不一的方法

    按圈圈中选择打印样式

  2. 把采集到的数据发送到一个Google Docs或者Google Form上 这个网站提供了参考和例子

    把采集到的数据发送到一个Google Docs或者Google Form上这个网站提供了参考和例子 http://www.instructables.com/id/Post-to-Google-Doc ...

  3. Failed to start component [StandardEngine[Tomcat].StandardHost[localhost].StandardContext[]] 错误(Day_25)

    错误:    在maven项目,web启动的时候报这个错误 Failed to start component [StandardEngine[Tomcat].StandardHost[localho ...

  4. 技术干货 | 源码解析 Github 上 14.1k Star 的 RocketMQ

    前言 Apache RocketMQ 作为广为人知的开源消息中间件,诞生于阿里巴巴,于 2016 年捐赠给了 Apache.从 RocketMQ 4.0 到如今最新的 v4.7.1,不论是在阿里巴巴内 ...

  5. java并发编程工具类JUC第一篇:BlockingQueue阻塞队列

    Java BlockingQueue接口java.util.concurrent.BlockingQueue表示一个可以存取元素,并且线程安全的队列.换句话说,当多线程同时从 JavaBlocking ...

  6. synchronized 的超多干货!

    前言 synchronized 这个关键字的重要性不言而喻,几乎可以说是并发.多线程必须会问到的关键字了.synchronized 会涉及到锁.升级降级操作.锁的撤销.对象头等.所以理解 synchr ...

  7. GO文件读写01---读文件

    打开文件 package main import ( "fmt" "os" ) /* buffer 缓冲区 utility 便利的工具 util 便捷工具(傻瓜 ...

  8. MapReduce —— MapTask阶段源码分析(Input环节)

    不得不说阅读源码的过程,极其痛苦 .Dream Car 镇楼 ~ ! 虽说整个MapReduce过程也就只有Map阶段和Reduce阶段,但是仔细想想,在Map阶段要做哪些事情?这一阶段具体应该包含数 ...

  9. 基本FTP服务: 文件传输协议

    1.服务端虚拟机Server,安装可以提供FTP服务软件 [root@server0 ~]# yum -y install vsftpd 2.虚拟机Server操作,启动 vsftpd服务,设置为开机 ...

  10. Centos flock 防止脚本重复运行

    如果crontab设定任务每分钟执行一次,但执行的任务需要花费5分钟,这时系统会再执行导致两个相同的任务在执行.发生这种情况下可能会出现一些并发问题,严重时会导致出现脏数据性能瓶颈等恶性循环.为了防止 ...