宿迁腾云网络网站建设公司

腾云网络 八年经验专注网站建设
  • 首页
  • 服务项目
    • 网站建设
    • 微信小程序
    • APP开发
    • SEO优化
  • 建站费用
  • 成功案例
    • 网站建设案例
    • 小程序案例
    • APP开发案例
    • SEO优化案例
  • 行业动态
    • 网站建设
    • SEO优化
    • 技术日志
  • 联系我们
    • 关于我们
首页 > 行业动态 > 技术日志 > swoole的自动取消订单还原库存等操作教程

swoole的自动取消订单还原库存等操作教程

2019-05-06

一、业务场景:当客户下单在指定的时间内如果没有付款,那我们需要将这笔订单取消掉,比如好的处理方法是运用延时取消,很多人首先想到的当然是crontab,这个也行,不过这里我们运用swoole的异步毫秒定时器来实现,同样也不会影响到当前程序的运行,具体可以参考:https://wiki.swoole.com/wiki/page/319.html


二、说明,order_status为1时代表客户下单确定,为2时代表客户已付款,为0时代表订单已取消(正是swoole来做的)


三、举例说明,库存表csdn_product_stock产品ID为1的产品库存数量为20,产品ID为2的库存数量为40,然后客户下单一笔产品ID1减10,产品ID2减20,所以库存表只够2次下单,例子中10秒后自动还原库存,如下图:

图解:1、第一次下完单产品ID1库存从20减到了10,产品ID2库存从40减到了20;2、第二次下完单产品ID的库存为0了,产品ID2的库存也为0了,3、第三次下单时,程序提示Out of stock;4、过了10秒钟(每个订单下单后往后推10秒),客户两次下单,由于没有付款(csdn_order表的order_status为1),产品1和产品2的库存被还原了(csdn_order表的order_status变为0),客户又可以继续下单了


swoole的自动取消订单还原库存等操作教程(图1)


1、所需要sql数据库表

DROP TABLE IF EXISTS `csdn_order`;
CREATE TABLE `csdn_order` (
  `order_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `order_amount` float(10,2) unsigned NOT NULL DEFAULT '0.00',
  `user_name` varchar(64) CHARACTER SET latin1 NOT NULL DEFAULT '',
  `order_status` tinyint(2) unsigned NOT NULL DEFAULT '0',
  `date_created` datetime NOT NULL,
  PRIMARY KEY (`order_id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;

DROP TABLE IF EXISTS `csdn_order_detail`;
CREATE TABLE `csdn_order_detail` (
  `detail_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `order_id` int(10) unsigned NOT NULL,
  `product_id` int(10) NOT NULL,
  `product_price` float(10,2) NOT NULL,
  `product_number` smallint(4) unsigned NOT NULL DEFAULT '0',
  `date_created` datetime NOT NULL,
  PRIMARY KEY (`detail_id`),
  KEY `idx_order_id` (`order_id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;

DROP TABLE IF EXISTS `csdn_product_stock`;
CREATE TABLE `csdn_product_stock` (
  `auto_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `product_id` int(10) NOT NULL,
  `product_stock_number` int(10) unsigned NOT NULL,
  `date_modified` datetime NOT NULL,
  PRIMARY KEY (`auto_id`),
  KEY `idx_product_id` (`product_id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

INSERT INTO `csdn_product_stock` VALUES ('1', '1', '20', '2018-09-13 19:36:19');
INSERT INTO `csdn_product_stock` VALUES ('2', '2', '40', '2018-09-13 19:36:19');


下面贴出来纯手工PHP,很多同学用了原生PHP,就不会运用到框架里去,其实都一样的,不要想得那么复杂就是了。只要一点就是你用多了,你就会这样觉得咯。


配置文件config.php  ,这个在框架的话,基本上都是配置好了。

<?php
$dbHost = "192.168.23.110";
$dbUser = "root";
$dbPassword = "123456";
$dbName = "test";
?>

swoole都是用在linux系统里的,这里的host你可以自己搭建虚拟主机,也可以网上购买属于自己的服务器


订单提交的文件order_submit.php,这里对订单生成,同时扣除库存的一系列操作

<?php
require("config.php");
try {
    $pdo = new PDO("mysql:host=" . $dbHost . ";dbname=" . $dbName, $dbUser, $dbPassword, array(PDO::ATTR_PERSISTENT => true));
    $pdo->setAttribute(PDO::ATTR_AUTOCOMMIT, 1);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $orderInfo = array(
        'order_amount' => 10.92,
        'user_name' => 'yusan',
        'order_status' => 1,
        'date_created' => 'now()',
        'product_lit' => array(
            0 => array(
                'product_id' => 1,
                'product_price' => 5.00,
                'product_number' => 10,
                'date_created' => 'now()'
            ),
            1 => array(
                'product_id' => 2,
                'product_price' => 5.92,
                'product_number' => 20,
                'date_created' => 'now()'
            )
        )
    );

    try{
        $pdo->beginTransaction();//开启事务处理

        $sql = 'insert into csdn_order (order_amount, user_name, order_status, date_created) values (:orderAmount, :userName, :orderStatus, now())';
        $stmt = $pdo->prepare($sql);  
        $affectedRows = $stmt->execute(array(':orderAmount' => $orderInfo['order_amount'], ':userName' => $orderInfo['user_name'], ':orderStatus' => $orderInfo['order_status']));
        $orderId = $pdo->lastInsertId();
        if(!$affectedRows) {
            throw new PDOException("Failure to submit order!");
        }
        foreach($orderInfo['product_lit'] as $productInfo) {

            $sqlProductDetail = 'insert into csdn_order_detail (order_id, product_id, product_price, product_number, date_created) values (:orderId, :productId, :productPrice, :productNumber, now())';
            $stmtProductDetail = $pdo->prepare($sqlProductDetail);  
            $stmtProductDetail->execute(array(':orderId' => $orderId, ':productId' =>  $productInfo['product_id'], ':productPrice' => $productInfo['product_price'], ':productNumber' => $productInfo['product_number']));

            $sqlCheck = "select product_stock_number from csdn_product_stock where product_id=:productId";  
            $stmtCheck = $pdo->prepare($sqlCheck);  
            $stmtCheck->execute(array(':productId' => $productInfo['product_id']));  
            $rowCheck = $stmtCheck->fetch(PDO::FETCH_ASSOC);
            if($rowCheck['product_stock_number'] < $productInfo['product_number']) {
                throw new PDOException("Out of stock, Failure to submit order!");
            }


            $sqlProductStock = 'update csdn_product_stock set product_stock_number=product_stock_number-:productNumber, date_modified=now() where product_id=:productId';
            $stmtProductStock = $pdo->prepare($sqlProductStock);  
            $stmtProductStock->execute(array(':productNumber' => $productInfo['product_number'], ':productId' => $productInfo['product_id']));
            $affectedRowsProductStock = $stmtProductStock->rowCount();

            //库存没有正常扣除,失败,库存表里的product_stock_number设置了为非负数
            //如果库存不足时,sql异常:SQLSTATE[22003]: Numeric value out of range: 1690 BIGINT UNSIGNED value is out of range in '(`test`.`csdn_product_stock`.`product_stock_number` - 20)'
            if($affectedRowsProductStock <= 0) {
                throw new PDOException("Out of stock, Failure to submit order!");
            }
        }
        echo "Successful, Order Id is:" . $orderId .",Order Amount is:" . $orderInfo['order_amount'] . "。";
        $pdo->commit();//提交事务
        //exec("php order_cancel.php -a" . $orderId . " &");
        pclose(popen('php order_cancel.php -a ' . $orderId . ' &', 'w'));
        //system("php order_cancel.php -a" . $orderId . " &", $phpResult);
        //echo $phpResult;
    }catch(PDOException $e){
        echo $e->getMessage();
        $pdo->rollback();
    }
    $pdo = null;
} catch (PDOException $e) {
    echo $e->getMessage();
}
?>

订单的延时处理order_cancel.php

<?php
require("config.php");
$queryString = getopt('a:');
$userParams = array($queryString);
appendLog(date("Y-m-d H:i:s") . "\t" . $queryString['a'] . "\t" . "start");

try {
    $pdo = new PDO("mysql:host=" . $dbHost . ";dbname=" . $dbName, $dbUser, $dbPassword, array(PDO::ATTR_PERSISTENT => true));
    $pdo->setAttribute(PDO::ATTR_AUTOCOMMIT, 0);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    swoole_timer_after(10000, function ($queryString) {
        global $queryString, $pdo;

        try{
            $pdo->beginTransaction();//开启事务处理

            $orderId = $queryString['a'];  
            $sql = "select order_status from csdn_order where order_id=:orderId";  
            $stmt = $pdo->prepare($sql);  
            $stmt->execute(array(':orderId' => $orderId));  
            $row = $stmt->fetch(PDO::FETCH_ASSOC);
            //$row['order_status'] === "1"代表已下单,但未付款,我们还原库存只针对未付款的订单
            if(isset($row['order_status']) && $row['order_status'] === "1") {
                $sqlOrderDetail = "select product_id, product_number from csdn_order_detail where order_id=:orderId";  
                $stmtOrderDetail = $pdo->prepare($sqlOrderDetail);  
                $stmtOrderDetail->execute(array(':orderId' => $orderId));  
                while($rowOrderDetail = $stmtOrderDetail->fetch(PDO::FETCH_ASSOC)) {
                    $sqlRestoreStock = "update csdn_product_stock set product_stock_number=product_stock_number + :productNumber, date_modified=now() where product_id=:productId";  
                    $stmtRestoreStock = $pdo->prepare($sqlRestoreStock);
                    $stmtRestoreStock->execute(array(':productNumber' => $rowOrderDetail['product_number'], ':productId' => $rowOrderDetail['product_id']));
                }

                $sqlRestoreOrder = "update csdn_order set order_status=:orderStatus where order_id=:orderId";  
                $stmtRestoreOrder = $pdo->prepare($sqlRestoreOrder);
                $stmtRestoreOrder->execute(array(':orderStatus' => 0, ':orderId' => $orderId));
            }

            $pdo->commit();//提交事务
        }catch(PDOException $e){
            echo $e->getMessage();
            $pdo->rollback();
        }
        $pdo = null;

        appendLog(date("Y-m-d H:i:s") . "\t" . $queryString['a'] . "\t" . "end\t" . json_encode($queryString));
    }, $pdo);

} catch (PDOException $e) {
    echo $e->getMessage();
}
function appendLog($str) {
    $dir = 'log.txt';
    $fh = fopen($dir, "a");
    fwrite($fh, $str . "\n");
    fclose($fh);
}
?>


Tag:
网站制作公众号

宿迁腾云网络网站建设公司 | 网站开发 | 网站制作 | 网站优化

咨询电话:13160355545

上一篇

返回栏目

下一篇

免责声明:本站所有文章和图片均来自用户分享和网络收集,文章和图片版权归原作者及原出处所有,仅供学习与参考,请勿用于商业用途,如果损害了您的权利,请联系网站客服处理。

热推

  • php 网站源码 论坛修改版流行PHP语言论坛程序官方网站取走网站完整数据库(图)论坛源码 php手机版
  • php restful 框架这使PHP开发框架的特点及应用缓存管理项目介绍restful 框架 net
  • 用php开发网站你的职业目标在哪里?有数百种可供选择?php如何开发网站
  • php开源在线客服系统微软开源开发者担忧被微软垄断开源系统工具在收购之后php开源在线客服系统
  • 通常前端开发在基础阶段掌握html+css+js+jq
  • 如何使用C语言来编写PHP的扩展,PHP作为一门开源语言
  • 一个百万级PHP站点的网站架构,你了解多少?
  • 高频CLI工具推荐(二):如何提高生产力?
  • 基于php的个人博客系统的实现知名IT信息技术社区全新升级,论坛软件系统采用开源PHP技术基于php的管理系统
  • php 开源搜索引擎北京一家公司开了好几个UE4项目,腾讯一般会配备至少10个3d地图引擎 渲染 开源

相关

标签

seo(1191) 市场营销(661) 网站制作(573) 网站建设(567) 搜索引擎(553) 网站(482) PHP(363) 编程语言(346) 建站(294) 关键词排名优化(267) 网站建设公司(245) 优化(216) seo排名(207) 域名(190) 软件(171) 网站优化(150) 搜索引擎优化(150) 外链(141) 科技(136) 网站关键词(124) 网站排名优化(123) 域名服务器(120) 网站排名(109) 时政(103) 排名优化(95) 搜索引擎收录(93) 网站设计(93) 电子商务(88) 引擎(86) 移动互联网(85) 开发框架(79) 开发(75) 网站服务器(74) 框架(68) 前端开发(68) 网站建设方案(66) 网站分析(66) 关键(64) 流量(63) 源码(62) 百度优化(62) 网站权重(61) 开放源代码(59) seo培训(53) php框架(51) 网页设计(51) 百度(51) 网站建设知识(50) 谷歌(50) 大数据(50)
宿迁腾云网络网站建设公司
网站建设
  • 私人定制
  • 标准模板建站
  • 经济模板建站
精品模板

宿迁腾云网络网站建设公司

联系电话:13160355545

公司地址:江苏省宿迁市丽景湾华庭北门都市花园公寓9楼907

联系邮箱:admin@tyweb.net

全国分站
  • 北京
  • 广东
  • 东莞 广州 中山 深圳 惠州 江门 珠海 汕头 佛山 湛江 河源 肇庆 潮州 清远 韶关 揭阳 阳江 云浮 茂名 梅州 汕尾
  • 山东
  • 济南 青岛 临沂 济宁 菏泽 烟台 泰安 淄博 潍坊 日照 威海 滨州 东营 聊城 德州 莱芜 枣庄
  • 江苏
  • 苏州 徐州 盐城 无锡 南京 南通 连云港 常州 扬州 镇江 淮安 泰州 宿迁
  • 河南
  • 郑州 南阳 新乡 安阳 洛阳 信阳 平顶山 周口 商丘 开封 焦作 驻马店 濮阳 三门峡 漯河 许昌 鹤壁 济源
  • 上海
  • 河北
  • 石家庄 唐山 保定 邯郸 邢台 沧州 秦皇岛 张家口 衡水 廊坊 承德
  • 浙江
  • 温州 宁波 杭州 台州 嘉兴 金华 湖州 绍兴 舟山 丽水 衢州
  • 陕西
  • 西安 咸阳 宝鸡 汉中 渭南 安康 榆林 商洛 延安 铜川
  • 湖南
  • 长沙 邵阳 常德 衡阳 株洲 湘潭 永州 岳阳 怀化 郴州 娄底 益阳 张家界 湘西
  • 重庆
  • 福建
  • 漳州 泉州 厦门 福州 莆田 宁德 三明 南平 龙岩
  • 天津
  • 云南
  • 昆明 红河 大理 文山 德宏 曲靖 昭通 楚雄 保山 玉溪 丽江 临沧 思茅 西双版纳 怒江 迪庆
  • 四川
  • 成都 绵阳 广元 达州 南充 德阳 广安 阿坝 巴中 遂宁 内江 凉山 攀枝花 乐山 自贡 泸州 雅安 宜宾 资阳 眉山 甘孜
  • 广西
  • 贵港 玉林 北海 南宁 柳州 桂林 梧州 钦州 来宾 河池 百色 贺州 崇左 防城港
  • 安徽
  • 芜湖 合肥 六安 宿州 阜阳 安庆 马鞍山 蚌埠 淮北 淮南 宣城 黄山 铜陵 亳州 池州 巢湖 滁州
  • 海南
  • 三亚 海口 琼海 文昌 东方
  • 江西
  • 南昌 赣州 上饶 吉安 九江 新余 抚州 宜春 景德镇 萍乡 鹰潭
  • 湖北
  • 武汉 宜昌 襄樊 荆州 恩施 孝感 黄冈 十堰 咸宁 黄石 仙桃 随州 天门 荆门 潜江 鄂州 神农架
  • 山西
  • 太原 大同 运城 长治 晋城 忻州 临汾 吕梁 晋中 阳泉 朔州
  • 辽宁
  • 大连 沈阳 丹东 辽阳 葫芦岛 锦州 朝阳 营口 鞍山 抚顺 阜新 本溪 盘锦 铁岭
  • 黑龙江
  • 齐齐哈尔 哈尔滨 大庆 佳木斯 双鸭山 牡丹江 鸡西 黑河 绥化 鹤岗 伊春 大兴安岭 七台河
  • 内蒙古
  • 赤峰 包头 通辽 呼和浩特 乌海 鄂尔多斯 呼伦贝尔
  • 贵州
  • 贵阳 黔东 黔南 遵义 黔西 毕节 铜仁 安顺 六盘水
  • 甘肃
  • 兰州 天水 庆阳 武威 酒泉 张掖 陇南 白银 定西 平凉 嘉峪关 临夏 金昌 甘南
  • 青海
  • 西宁 海西 海东 海北 果洛 玉树 黄南
  • 新疆
  • 乌鲁木齐 伊犁 昌吉 石河子 哈密
  • 西藏
  • 拉萨 山南 林芝 日喀则
  • 吉林
  • 长春 白山 白城 延边 松原 辽源 通化 四平
  • 宁夏
  • 银川 吴忠 中卫 石嘴山 固原
SiteMap
网站地图
TAG标签
Copyright © 2017-2025 TYWEB.NET 宿迁腾云网络科技有限公司 ALL RIGHTS RESERVED.   苏ICP备17033535号-1

热门搜索

下载 2025 2026 2024 2023 请输入关健词 货源 货货源 虚拟
  • 客服

    在线客服

  • 电话

    13160355545

  • 微信

精品模板
建站费用
成功案例
联系我们