Heim >PHP-Framework >Swoole >Dieses Mal habe ich Swoole verwendet, um Bestellungen zu verzögern und den Lagerbestand wiederherzustellen!

Dieses Mal habe ich Swoole verwendet, um Bestellungen zu verzögern und den Lagerbestand wiederherzustellen!

藏色散人
藏色散人nach vorne
2021-07-30 14:09:262825Durchsuche

Dieses Mal habe ich Swoole verwendet, um Bestellungen zu verzögern und den Lagerbestand wiederherzustellen!

1. Geschäftsszenario: Wenn ein Kunde eine Bestellung aufgibt und nicht innerhalb der angegebenen Zeit bezahlt, müssen wir die Bestellung beispielsweise stornieren, indem wir natürlich eine verzögerte Stornierung verwenden Das erste, woran viele Leute denken, ist Crontab. Dies ist auch möglich, aber hier verwenden wir den asynchronen Millisekunden-Timer von Swoole, um es zu implementieren, was auch keinen Einfluss auf die Ausführung des aktuellen Programms hat.

2. Erläuterung: Wenn order_status 1 ist, bedeutet dies, dass der Kunde eine Bestellung aufgegeben hat, wenn er 2 ist, bedeutet dies, dass der Kunde bezahlt hat, und wenn er 0 ist, bedeutet dies, dass die Bestellung storniert wurde (dies ist das, was Swoole macht)

Drei, zum Beispiel die Inventartabelle csdn_product_stock Produkt. Die Lagerbestandsmenge von Produkt-ID 1 beträgt 20 und die Lagerbestandsmenge von Produkt-ID 2 beträgt 40. Wenn der Kunde dann eine Bestellung aufgibt, wird Produkt-ID1 reduziert um 10 und die Produkt-ID2 wird um 20 reduziert. Daher reicht die Lagerbestandstabelle nur für 2 Bestellungen. Im Beispiel wird der Lagerbestand nach 10 Sekunden automatisch wiederhergestellt.

Wie unten gezeigt, Diagramm:

1. Nach der ersten Bestellung wurde der Bestand von Produkt ID1 von 20 auf 10 und der Bestand von Produkt ID2 von 40 auf 20 reduziert Bei der zweiten Bestellung war der Lagerbestand der Produkt-ID 0, der Lagerbestand der Produkt-ID2 war ebenfalls 0,

3 Bei der dritten Bestellung meldet das Programm nach jeweils 10 Sekunden „Nicht vorrätig“. Die Bestellung wird um 10 Sekunden verschoben. Da keine Zahlung erfolgt ist (der Bestellstatus der Tabelle „csdn_order“ ist 1), wurde der Bestand von Produkt 1 und Produkt 2 wiederhergestellt (der Bestellstatus der Tabelle „csdn_order“ wurde zu 0). , und der Kunde kann weiterhin Bestellungen aufgeben

Dieses Mal habe ich Swoole verwendet, um Bestellungen zu verzögern und den Lagerbestand wiederherzustellen! 1. Die erforderliche SQL-Datenbanktabelle

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');

wird unten mit rein manuellem PHP veröffentlicht und wird es tatsächlich nicht auf das Framework anwenden sind alle gleich, denken Sie also nicht so kompliziert. Solange Sie es zu oft verwenden, werden Sie dieses Gefühl haben.

Konfigurationsdatei config.php, wenn diese im Framework vorhanden ist, ist sie grundsätzlich konfiguriert.

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

swoole werden alle in Linux-Systemen verwendet. Sie können hier Ihren eigenen virtuellen Host für den Host erstellen oder Ihren eigenen Server online kaufen. Die Auftragsübermittlungsdatei order_submit.php wird hier generiert und der Bestand wird abgezogen Reihe von Vorgängen

<?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(
        &#39;order_amount&#39; => 10.92,
        &#39;user_name&#39; => &#39;yusan&#39;,
        &#39;order_status&#39; => 1,
        &#39;date_created&#39; => &#39;now()&#39;,
        &#39;product_lit&#39; => array(
            0 => array(
                &#39;product_id&#39; => 1,
                &#39;product_price&#39; => 5.00,
                &#39;product_number&#39; => 10,
                &#39;date_created&#39; => &#39;now()&#39;
            ),
            1 => array(
                &#39;product_id&#39; => 2,
                &#39;product_price&#39; => 5.92,
                &#39;product_number&#39; => 20,
                &#39;date_created&#39; => &#39;now()&#39;
            )
        )
    );
    try{
        $pdo->beginTransaction();//开启事务处理
        $sql = &#39;insert into csdn_order (order_amount, user_name, order_status, date_created) values (:orderAmount, :userName, :orderStatus, now())&#39;;
        $stmt = $pdo->prepare($sql);  
        $affectedRows = $stmt->execute(array(&#39;:orderAmount&#39; => $orderInfo[&#39;order_amount&#39;], &#39;:userName&#39; => $orderInfo[&#39;user_name&#39;], &#39;:orderStatus&#39; => $orderInfo[&#39;order_status&#39;]));
        $orderId = $pdo->lastInsertId();
        if(!$affectedRows) {
            throw new PDOException("Failure to submit order!");
        }
        foreach($orderInfo[&#39;product_lit&#39;] as $productInfo) {
            $sqlProductDetail = &#39;insert into csdn_order_detail (order_id, product_id, product_price, product_number, date_created) values (:orderId, :productId, :productPrice, :productNumber, now())&#39;;
            $stmtProductDetail = $pdo->prepare($sqlProductDetail);  
            $stmtProductDetail->execute(array(&#39;:orderId&#39; => $orderId, &#39;:productId&#39; =>  $productInfo[&#39;product_id&#39;], &#39;:productPrice&#39; => $productInfo[&#39;product_price&#39;], &#39;:productNumber&#39; => $productInfo[&#39;product_number&#39;]));
            $sqlCheck = "select product_stock_number from csdn_product_stock where product_id=:productId";  
            $stmtCheck = $pdo->prepare($sqlCheck);  
            $stmtCheck->execute(array(&#39;:productId&#39; => $productInfo[&#39;product_id&#39;]));  
            $rowCheck = $stmtCheck->fetch(PDO::FETCH_ASSOC);
            if($rowCheck[&#39;product_stock_number&#39;] < $productInfo[&#39;product_number&#39;]) {
                throw new PDOException("Out of stock, Failure to submit order!");
            }
            $sqlProductStock = &#39;update csdn_product_stock set product_stock_number=product_stock_number-:productNumber, date_modified=now() where product_id=:productId&#39;;
            $stmtProductStock = $pdo->prepare($sqlProductStock);  
            $stmtProductStock->execute(array(&#39;:productNumber&#39; => $productInfo[&#39;product_number&#39;], &#39;:productId&#39; => $productInfo[&#39;product_id&#39;]));
            $affectedRowsProductStock = $stmtProductStock->rowCount();
            //库存没有正常扣除,失败,库存表里的product_stock_number设置了为非负数
            //如果库存不足时,sql异常:SQLSTATE[22003]: Numeric value out of range: 1690 BIGINT UNSIGNED value is out of range in &#39;(`test`.`csdn_product_stock`.`product_stock_number` - 20)&#39;
            if($affectedRowsProductStock <= 0) {
                throw new PDOException("Out of stock, Failure to submit order!");
            }
        }
        echo "Successful, Order Id is:" . $orderId .",Order Amount is:" . $orderInfo[&#39;order_amount&#39;] . "。";
        $pdo->commit();//提交事务
        //exec("php order_cancel.php -a" . $orderId . " &");
        pclose(popen(&#39;php order_cancel.php -a &#39; . $orderId . &#39; &&#39;, &#39;w&#39;));
        //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();
}
?>

Verzögerte Bearbeitung von Bestellungen order_cancel.php

<?php
require("config.php");
$queryString = getopt(&#39;a:&#39;);
$userParams = array($queryString);
appendLog(date("Y-m-d H:i:s") . "\t" . $queryString[&#39;a&#39;] . "\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[&#39;a&#39;];  
            $sql = "select order_status from csdn_order where order_id=:orderId";  
            $stmt = $pdo->prepare($sql);  
            $stmt->execute(array(&#39;:orderId&#39; => $orderId));  
            $row = $stmt->fetch(PDO::FETCH_ASSOC);
            //$row[&#39;order_status&#39;] === "1"代表已下单,但未付款,我们还原库存只针对未付款的订单
            if(isset($row[&#39;order_status&#39;]) && $row[&#39;order_status&#39;] === "1") {
                $sqlOrderDetail = "select product_id, product_number from csdn_order_detail where order_id=:orderId";  
                $stmtOrderDetail = $pdo->prepare($sqlOrderDetail);  
                $stmtOrderDetail->execute(array(&#39;:orderId&#39; => $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(&#39;:productNumber&#39; => $rowOrderDetail[&#39;product_number&#39;], &#39;:productId&#39; => $rowOrderDetail[&#39;product_id&#39;]));
                }
                $sqlRestoreOrder = "update csdn_order set order_status=:orderStatus where order_id=:orderId";  
                $stmtRestoreOrder = $pdo->prepare($sqlRestoreOrder);
                $stmtRestoreOrder->execute(array(&#39;:orderStatus&#39; => 0, &#39;:orderId&#39; => $orderId));
            }
            $pdo->commit();//提交事务
        }catch(PDOException $e){
            echo $e->getMessage();
            $pdo->rollback();
        }
        $pdo = null;
        appendLog(date("Y-m-d H:i:s") . "\t" . $queryString[&#39;a&#39;] . "\t" . "end\t" . json_encode($queryString));
    }, $pdo);
} catch (PDOException $e) {
    echo $e->getMessage();
}
function appendLog($str) {
    $dir = &#39;log.txt&#39;;
    $fh = fopen($dir, "a");
    fwrite($fh, $str . "\n");
    fclose($fh);
}
?>

Weitere technische Artikel zu Swoole finden Sie in der Spalte „Swoole-Tutorial

“!

Das obige ist der detaillierte Inhalt vonDieses Mal habe ich Swoole verwendet, um Bestellungen zu verzögern und den Lagerbestand wiederherzustellen!. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:磊丰. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen