1. ビジネス シナリオ: 顧客が注文を出し、指定された時間内に支払いが行われない場合、注文をキャンセルする必要があります。たとえば、それに対処する良い方法もちろん、多くの人が最初に思いつくのは crontab です。これも可能ですが、ここでは swoole の非同期ミリ秒タイマーを使用して実装しています。これも現在のプログラムの実行には影響しません。
2. 説明: 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. 2 回目の注文後、単一の製品 ID の在庫は 0 になり、製品 ID2 の在庫も 0 になります。
3. 3 回目の注文時に、プログラムは Out を要求します在庫;
4. 10 秒後 (それぞれの注文が行われてから 10 秒後)、顧客は 2 回注文しました。支払いがなかったため (csdn_order テーブルの order_status は 1 でした)、在庫は製品 1 と製品 2 が復元されました (csdn_order テーブルの order_status が 1 に変更されました)。0)、顧客は注文を続行できます
1. 必要な SQL データベースtable
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 システムで使用されます。ここでホスト用に独自の仮想ホストを構築することも、オンラインで独自のサーバーを購入することもできます。
注文送信ファイル 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); } ?>
その他の swoole の技術記事については、swoole チュートリアル#をご覧ください。 ## カラム !
以上が今回はswooleを使って注文を遅らせて在庫を回復してみました!の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

workerman 对比 swoole 实际开发项目中,你会选择哪个?对于新手学哪个较好,有什么建议吗?

在现代的应用开发中,异步编程在高并发场景下变得越来越重要。Swoole和Go是两个非常流行的异步编程框架,它们都具有高效的异步能力,但是很多人在选择使用哪个框架时会陷入困境。本文将探讨如何选择Swoole和Go,以及它们的优缺点。

你学会 Swoole 需要多久呢?这个问题其实非常难回答,因为它涉及到很多因素,比如你的编程基础、学习动力、时间安排等等。不过,在这篇文章中,我将分享一些我自己学习 Swoole 的经验和建议,希望能够对你有所帮助。

Swoole是一个基于PHP的开源高性能网络通信框架,它提供了TCP/UDP服务器和客户端的实现,以及多种异步IO、协程等高级特性。随着Swoole日益流行,许多人开始关心Web服务器使用Swoole的问题。为什么当前的Web服务器(如Apache、Nginx、OpenLiteSpeed等)不使用Swoole呢?让我们探讨一下这个问题。

以下为大家整理了php异步通信框架Swoole的视频教程,不需要从迅雷、百度云之类的第三方平台下载,全部在线免费观看。教程由浅入深,有php基础的人就能学习,从安装到案例讲解,全面详细,帮助你更快更好的掌握Swoole框架!

怎么在docker中搭建swoole环境?下面本篇文章给大家介绍一下用docker搭建swoole环境的方法,希望对大家有所帮助!

php让Swoole|Pool进程池实现Redis持久连接进程池,基于Swoole\Server的Manager管理进程模块实现。可管理多个工作进程,相比Process实现多进程,Process\Pool更加简单,封装层次更高,开发者无需编写过多代码即可实现进程管理功能,配合Co\Server可以创建纯协程风格的,能利用多核CPU的服务端程序。Swoole进程池实现redis数据读取如下案例,通过WorkerStart启动Redis进程池,并持久读取Redis列表数据;当WorkerStop断开

Swoole是一种基于PHP语言的网络通信框架,它能够提供异步、并发、高性能的HTTP、WebSocket以及TCP/UDP协议服务器和客户端,在开发Web服务以及网络通信应用时都有很大的用途,广泛应用于一些互联网公司。本文将介绍如何使用Swoole调用。


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

Safe Exam Browser
Safe Exam Browser は、オンライン試験を安全に受験するための安全なブラウザ環境です。このソフトウェアは、あらゆるコンピュータを安全なワークステーションに変えます。あらゆるユーティリティへのアクセスを制御し、学生が無許可のリソースを使用するのを防ぎます。

DVWA
Damn Vulnerable Web App (DVWA) は、非常に脆弱な PHP/MySQL Web アプリケーションです。その主な目的は、セキュリティ専門家が法的環境でスキルとツールをテストするのに役立ち、Web 開発者が Web アプリケーションを保護するプロセスをより深く理解できるようにし、教師/生徒が教室環境で Web アプリケーションを教え/学習できるようにすることです。安全。 DVWA の目標は、シンプルでわかりやすいインターフェイスを通じて、さまざまな難易度で最も一般的な Web 脆弱性のいくつかを実践することです。このソフトウェアは、

SublimeText3 英語版
推奨: Win バージョン、コードプロンプトをサポート!

EditPlus 中国語クラック版
サイズが小さく、構文の強調表示、コード プロンプト機能はサポートされていません

SublimeText3 Linux 新バージョン
SublimeText3 Linux 最新バージョン
