我的思路如下(伪代码):

sql1:查询商品库存
if(库存数量 > 0)
{
//生成订单...
sql2:同时库存-1
}
当没有并发时,上面的流程看起来是再正常不过了,假设同时两个人下单,而库存只有1个了,在sql1阶段两个人查询到的库存都是>0的,于是最终都执行了sql2,库存最后变为-1,超售了,这不是我们想要的结果吧。
解决这个问题比较流行的思路我总结了下:
1.用额外的单进程处理一个队列,下单请求放到队列里,一个个处理,就不会有并发的问题了,但是要额外的开启后台进程以及延迟问题,这里暂不予考虑。这里我可使用消息队列,我们常用到Memcacheq、Radis。 比如:有100张票可供用户抢,那么就可以把这100张票放到缓存中,读写时不要加锁。 当并发量大的时候,可能有500人左右抢票成功,这样对于500后面的请求可以直接转到活动结束的静态页面。进去的500个人中有400个人是不可能获得商品的。所以可以根据进入队列的先后顺序只能前100个人购买成功。后面400个人就直接转到活动结束页面。当然进去500个人只是举个例子,至于多少可以自己调整。而活动结束页面一定要用静态页面,不要用数据库。这样就减轻了数据库的压力。
2.mysql乐观锁,意思是比如总库存是2,抢购事件提交时,立马将库存+1,那么此时库存是3,然后订单生成后,在更新库存前再查询一次库存(因为订单生成理所当然库存-1,但是先不急,再查一次库存返回结果是3),看看跟预期的库存数量(这里预期的库存是3)是否保持一致,不一致就回滚,提示用户库存不足。这里说道悲观锁,可能有朋友会问,那一定有乐观锁了吧??这里我就浅谈下我所了解的悲观与乐观锁了
悲观锁与乐观锁是两种常见的资源并发锁设计思路,也是并发编程中一个非常基础的概念。本文将对这两种常见的锁机制在数据库数据上的实现进行比较系统的介绍。
悲观锁(Pessimistic Lock)
悲观锁的特点是先获取锁,再进行业务操作,即“悲观”的认为获取锁是非常有可能失败的,因此要先确保获取锁成功再进行业务操作。通常所说的“一锁二查三更新”即指的是使用悲观锁。通常来讲在数据库上的悲观锁需要数据库本身提供支持,即通过常用的select … for update操作来实现悲观锁。当数据库执行select for update时会获取被select中的数据行的行锁,因此其他并发执行的select for update如果试图选中同一行则会发生排斥(需要等待行锁被释放),因此达到锁的效果。select for update获取的行锁会在当前事务结束时自动释放,因此必须在事务中使用。
这里需要注意的一点是不同的数据库对select for update的实现和支持都是有所区别的,例如oracle支持select for update no wait,表示如果拿不到锁立刻报错,而不是等待,mysql就没有no wait这个选项。另外mysql还有个问题是select for update语句执行中所有扫描过的行都会被锁上,这一点很容易造成问题。因此如果在mysql中用悲观锁务必要确定走了索引,而不是全表扫描。
乐观锁(Optimistic Lock)
乐观锁的特点先进行业务操作,不到万不得已不去拿锁。即“乐观”的认为拿锁多半是会成功的,因此在进行完业务操作需要实际更新数据的最后一步再去拿一下锁就好。
乐观锁在数据库上的实现完全是逻辑的,不需要数据库提供特殊的支持。一般的做法是在需要锁的数据上增加一个版本号,或者时间戳,然后按照如下方式实现:
1. SELECT data AS old_data, version AS old_version FROM …;
2. 根据获取的数据进行业务操作,得到new_data和new_version
3. UPDATE SET data = new_data, version = new_version WHERE version = old_version
if (updated row > 0) {
// 乐观锁获取成功,操作完成
} else {
// 乐观锁获取失败,回滚并重试
}
乐观锁是否在事务中其实都是无所谓的,其底层机制是这样:在数据库内部update同一行的时候是不允许并发的,即数据库每次执行一条update语句时会获取被update行的写锁,直到这一行被成功更新后才释放。因此在业务操作进行前获取需要锁的数据的当前版本号,然后实际更新数据时再次对比版本号确认与之前获取的相同,并更新版本号,即可确认这之间没有发生并发的修改。如果更新失败即可认为老版本的数据已经被并发修改掉而不存在了,此时认为获取锁失败,需要回滚整个业务操作并可根据需要重试整个过程。好吧,在此唠叨总结下这两个锁:
乐观锁在不发生取锁失败的情况下开销比悲观锁小,但是一旦发生失败回滚开销则比较大,因此适合用在取锁失败概率比较小的场景,可以提升系统并发性能
乐观锁还适用于一些比较特殊的场景,例如在业务操作过程中无法和数据库保持连接等悲观锁无法适用的地方
3.根据update结果来判断,我们可以在sql2的时候加一个判断条件update table set 库存=xxx where 库存>0,如果返回false,则说明库存不足,并回滚事务。
4.借助文件排他锁,在处理下单请求的时候,用flock锁定一个文件,如果锁定失败说明有其他订单正在处理,此时要么等待要么直接提示用户"服务器繁忙"
大致代码如下:
阻塞(等待)模式
<?php
$fp = fopen("lock.txt", "w+");
if(flock($fp,LOCK_EX)) //锁定当前指针,,,
{
//..处理订单
flock($fp,LOCK_UN);
}
fclose($fp);
?>
非阻塞模式
<?php
$fp = fopen("lock.txt", "w+");
if(flock($fp,LOCK_EX | LOCK_NB))
{
//..处理订单
flock($fp,LOCK_UN);
}
else
{
echo "系统繁忙,请稍后再试";
}
fclose($fp);
?>
5.如果是分布式集群服务器,就需要一个或多个队列服务器 小米和淘宝的抢购还是有稍许不同的,小米重在抢的那瞬间,抢到了名额,就是你的,你就可以下单结算。而淘宝则重在付款的时候的过滤,做了多层过滤,比如要卖10件商品,他会让大于10的用户抢到,在付款的时候再进行并发过滤,一层层的减少一瞬间的并发量。
6.使用redis锁 product_lock_key 为票锁key 当product_key存在于redis中时,所有用户都可以进入下单流程。 当进入支付流程时,首先往redis存放sadd(product_lock_key, “1″),如果返回成功,进入支付流程。如果不成,则说明已经有人进入支付流程,则线程等待N秒,递归执行sadd操作。
当然类似于淘宝双11的疯抢架构远远比我说滴这些复杂多啦....更多解决方案需要不停滴去实战中获取心得....大家有好的解决思路清随时共享留言哈
# php
# 高并发
# 简单介绍PHP非阻塞模式
# php使用flock阻塞写入文件和非阻塞写入文件的实例讲解
# 关于PHP中协程和阻塞的一些理解与思考
# PHP使用curl_multi实现并发请求的方法示例
# php处理抢购类功能的高并发请求
# 并发下常见的加锁及锁的PHP具体实现代码
# php并发加锁示例
# php多线程并发实现方法
# PHP接口并发测试的方法(推荐)
# PHP实现非阻塞模式的方法分析
# 都是
# 下单
# 淘宝
# 转到
# 能有
# 递归
# 抢到
# 重试
# 则说
# 而不是
# 瞬间
# 我就
# 是在
# 有个
# 我说
# 走了
# 过了
# 是有
# 多个
# 在此
相关文章:
如何通过西部建站助手安装IIS服务器?
如何零成本快速生成个人自助网站?
网站制作模板下载什么软件,ppt模板免费下载网站?
海南网站制作公司有哪些,海口网是哪家的?
微信小程序 input输入框控件详解及实例(多种示例)
网站海报制作教学视频教程,有什么免费的高清可商用图片网站,用于海报设计?
在线教育网站制作平台,山西立德教育官网?
如何设置并定期更换建站之星安全管理员密码?
威客平台建站流程解析:高效搭建教程与设计优化方案
网站制作和推广的区别,想自己建立一个网站做推广,有什么快捷方法马上做好一个网站?
如何正确下载安装西数主机建站助手?
实现点击下箭头变上箭头来回切换的两种方法【推荐】
婚礼视频制作网站,学习*后期制作的网站有哪些?
猪八戒网站制作视频,开发一个猪八戒网站,大约需要多少?或者自己请程序员,需要什么程序员,多少程序员能完成?
如何快速上传自定义模板至建站之星?
专业型网站制作公司有哪些,我设计专业的,谁给推荐几个设计师兼职类的网站?
jQuery 常见小例汇总
道歉网站制作流程,世纪佳缘致歉小吴事件,相亲网站身份信息伪造该如何稽查?
如何在服务器上配置二级域名建站?
如何获取免费开源的自助建站系统源码?
制作网站外包平台,自动化接单网站有哪些?
如何快速搭建高效可靠的建站解决方案?
家族网站制作贴纸教程视频,用豆子做粘帖画怎么制作?
招商网站制作流程,网站招商广告语?
如何在阿里云部署织梦网站?
专业网站建设制作报价,网页设计制作要考什么证?
Java解压缩zip - 解压缩多个文件或文件夹实例
如何配置FTP站点权限与安全设置?
如何快速生成ASP一键建站模板并优化安全性?
相册网站制作软件,图片上的网址怎么复制?
魔方云NAT建站如何实现端口转发?
建站中国必看指南:CMS建站系统+手机网站搭建核心技巧解析
临沂网站制作企业,临沂第三中学官方网站?
如何将凡科建站内容保存为本地文件?
浅析上传头像示例及其注意事项
h5在线制作网站电脑版下载,h5网页制作软件?
潍坊网站制作公司有哪些,潍坊哪家招聘网站好?
深圳网站制作费用多少钱,读秀,深圳文献港这样的网站很多只提供网上试读,但有些人只要提供试读的文章就能全篇下载,这个是怎么弄的?
简历在线制作网站免费版,如何创建个人简历?
Android自定义listview布局实现上拉加载下拉刷新功能
PHP正则匹配日期和时间(时间戳转换)的实例代码
建站之星代理如何获取技术支持?
兔展官网 在线制作,怎样制作微信请帖?
网站制作公司广州有几家,广州尚艺美发学校网站是多少?
小自动建站系统:AI智能生成+拖拽模板,多端适配一键搭建
湖南网站制作公司,湖南上善若水科技有限公司做什么的?
怎么用手机制作网站链接,dw怎么把手机适应页面变成网页?
C++如何使用std::optional?(处理可选值)
广州网站建站公司选择指南:建站流程与SEO优化关键词解析
建站之星24小时客服电话如何获取?
*请认真填写需求信息,我们会在24小时内与您取得联系。