一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語(yǔ)言|JavaScript|易語(yǔ)言|vb.net|

服務(wù)器之家 - 編程語(yǔ)言 - PHP教程 - thinkphp6使用mysql悲觀鎖解決商品超賣問(wèn)題的實(shí)現(xiàn)

thinkphp6使用mysql悲觀鎖解決商品超賣問(wèn)題的實(shí)現(xiàn)

2021-11-29 15:22每天至少八杯水1688 PHP教程

這篇文章主要介紹了thinkphp6使用mysql悲觀鎖解決商品超賣問(wèn)題的實(shí)現(xiàn),感興趣的可以了解一下

悲觀鎖介紹(百科):

悲觀鎖,正如其名,它指的是對(duì)數(shù)據(jù)被外界(包括本系統(tǒng)當(dāng)前的其他事務(wù),以及來(lái)自外部系統(tǒng)的事務(wù)處理)修改持保守態(tài)度,因此,在整個(gè)數(shù)據(jù)處理過(guò)程中,將數(shù)據(jù)處于鎖定狀態(tài)。悲觀鎖的實(shí)現(xiàn),往往依靠數(shù)據(jù)庫(kù)提供的鎖機(jī)制(也只有數(shù)據(jù)庫(kù)層提供的鎖機(jī)制才能真正保證數(shù)據(jù)訪問(wèn)的排他性,否則,即使在本系統(tǒng)中實(shí)現(xiàn)了加鎖機(jī)制,也無(wú)法保證外部系統(tǒng)不會(huì)修改數(shù)據(jù))。

使用場(chǎng)景舉例:以MySQL InnoDB為例

商品goods表,假設(shè)商品的id為1,購(gòu)買數(shù)量為1,status為1表示上架中,2表示下架。現(xiàn)在用戶購(gòu)買此商品,在不是高并發(fā)的情況下處理邏輯是:

  • 查找此商品的信息;
  • 檢查商品庫(kù)存是否大于購(gòu)買數(shù)量;
  • 修改商品庫(kù)存和銷量;

上面這種場(chǎng)景在高并發(fā)訪問(wèn)的情況下很可能會(huì)出現(xiàn)問(wèn)題。如果商品庫(kù)存是100個(gè),高并發(fā)的情況下可能會(huì)有1000個(gè)同時(shí)訪問(wèn),在到達(dá)第2步的時(shí)候,都會(huì)檢測(cè)通過(guò)。這樣會(huì)出現(xiàn)商品庫(kù)存是-900個(gè)的情況。顯然著不滿足需求!!!

商品表結(jié)構(gòu):

CREATE TABLE `goods` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(100) COLLATE utf8_unicode_ci NOT NULL DEFAULT "",
  `status` tinyint(1) NOT NULL DEFAULT "1",
  `total` int(11) NOT NULL DEFAULT "0",
  `sell` int(11) NOT NULL DEFAULT "100",
  `price` decimal(10,2) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
 
INSERT INTO `test`.`goods`(`id`, `name`, `status`, `total`, `sell`, `price`) VALUES (1, "商品", 1, 0, 100, 15.00);

訂單表結(jié)構(gòu):

CREATE TABLE `orders` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `uid` int(11) NOT NULL DEFAULT "0",
  `create_time` datetime NOT NULL,
  `status` tinyint(1) NOT NULL DEFAULT "1",
  `goods_id` int(11) NOT NULL DEFAULT "0",
  `order_no` varchar(200) COLLATE utf8_unicode_ci NOT NULL DEFAULT "",
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

使用悲觀鎖處理。

當(dāng)我們?cè)诓樵兂鰃oods信息后就把當(dāng)前的數(shù)據(jù)鎖定,直到我們修改完畢后再解鎖。那么在這個(gè)過(guò)程中,因?yàn)間oods被鎖定了,就不會(huì)出現(xiàn)有第三者來(lái)對(duì)其進(jìn)行修改了。

注:要使用悲觀鎖,我們必須關(guān)閉mysql數(shù)據(jù)庫(kù)的自動(dòng)提交屬性,因?yàn)镸ySQL默認(rèn)使用autocommit模式,也就是說(shuō),當(dāng)你執(zhí)行一個(gè)更新操作后,MySQL會(huì)立刻將結(jié)果進(jìn)行提交。thinkphp6中使用事務(wù),手動(dòng)進(jìn)行提交回滾。

<?php
 
namespace appcontroller;
 
use appBaseController;
use thinkfacadeDb;
 
class Test extends BaseController
{
 
    /**
     * 不加鎖
     * @return string|void
     */
    public function test_1()
    {
        $num = 1;
        $goods_id = 1;
        Db::startTrans();
        try {
            $where = [];
            $where["id"] = $goods_id;
            $where["status"] = 1;
            $goods_info = Db::table("goods")->where($where)->find();
            if (empty($goods_info)) {
                return "商品不存在";
            }
            $total = $goods_info["total"];
            $sell = $goods_info["sell"];
            if ($total < $num) {
                return "庫(kù)存不足";
            }
            $data["total"] = $total-$num;
            $data["sell"] = $sell+$num;
            $res = Db::table("goods")->where(["id"=>$goods_id])->update($data);
            $order_data = [];
            $order_data["uid"] = rand(1000,9999);
            $order_data["status"] = 1;
            $order_data["create_time"] = date("Y-m-d H:i:s");
            $order_data["goods_id"] = $goods_id;
            $order_data["order_no"] = date("YmdHis").rand(1000,10000);
            $order_res = Db::table("orders")->insert($order_data);
            Db::commit();
        } catch (Exception $e) {
            // 回滾事務(wù)
            Db::rollback();
            echo $e->getMessage();
            exit("rollback");
        }
        echo "請(qǐng)求成功";
    }
 
    /**
     * 加鎖--悲觀鎖
     * @return string|void
     */
    public function test_2()
    {
        $num = 1;
        $goods_id = 1;
        Db::startTrans();
        try {
            $where = [];
            $where["id"] = $goods_id;
            $where["status"] = 1;
            $goods_info = Db::table("goods")->lock(true)->where($where)->find();
            if (empty($goods_info)) {
                return "商品不存在";
            }
            $total = $goods_info["total"];
            $sell = $goods_info["sell"];
            if ($total < $num) {
                return "庫(kù)存不足";
            }
            $data["total"] = $total-$num;
            $data["sell"] = $sell+$num;
            $res = Db::table("goods")->where(["id"=>$goods_id])->update($data);
            $order_data = [];
            $order_data["uid"] = rand(1000,9999);
            $order_data["status"] = 1;
            $order_data["goods_id"] = $goods_id;
            $order_data["order_no"] = date("YmdHis").rand(1000,10000);
            $order_data["create_time"] = date("Y-m-d H:i:s");
            $order_res = Db::table("orders")->insert($order_data);
            Db::commit();
        } catch (Exception $e) {
            // 回滾事務(wù)
            Db::rollback();
            echo $e->getMessage();
            exit("rollback");
 
        }
        echo "請(qǐng)求成功";
    }
 
}

使用jmeter工具測(cè)試,創(chuàng)建線程測(cè)試組:

關(guān)于使用jmeter創(chuàng)建測(cè)試高并發(fā)例子,可查看:使用JMeter進(jìn)行高并發(fā)測(cè)試_左右..的博客-CSDN博客_jmeter高并發(fā)測(cè)試

這里模擬1s內(nèi)1000個(gè)用戶同時(shí)訪問(wèn)

thinkphp6使用mysql悲觀鎖解決商品超賣問(wèn)題的實(shí)現(xiàn)

 創(chuàng)建http請(qǐng)求:

thinkphp6使用mysql悲觀鎖解決商品超賣問(wèn)題的實(shí)現(xiàn)

添加察看結(jié)果樹(shù):

thinkphp6使用mysql悲觀鎖解決商品超賣問(wèn)題的實(shí)現(xiàn)

 測(cè)試開(kāi)始:

100個(gè)商品不加鎖的結(jié)果:

thinkphp6使用mysql悲觀鎖解決商品超賣問(wèn)題的實(shí)現(xiàn)

100個(gè)商品庫(kù)存,生成訂單187個(gè),超賣87個(gè)商品,這在項(xiàng)目開(kāi)發(fā)中是絕對(duì)不允許的。

100個(gè)商品,加鎖結(jié)果:

thinkphp6使用mysql悲觀鎖解決商品超賣問(wèn)題的實(shí)現(xiàn)

 加鎖,得到解決。

到此這篇關(guān)于thinkphp6使用mysql悲觀鎖解決商品超賣問(wèn)題的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)thinkphp6 商品超賣內(nèi)容請(qǐng)搜索服務(wù)器之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持服務(wù)器之家!

原文鏈接:https://blog.csdn.net/W07028057/article/details/121455332

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国语第一次处破女 | 7mav视频| 久9视频这里只有精品123 | 日本无翼乌漫画 | 亚洲色图图 | 国产日韩欧美不卡www | 亚洲国产剧情中文视频在线 | 日本草草视频 | 欧美高清在线不卡免费观看 | 丰满艳妇亲伦视频 | 国产精品久久久久网站 | 五月桃花网婷婷亚洲综合 | 性俄罗斯xxxxxhd | 深夜网站在线观看 | 精品久久久久久国产 | 99色在线视频 | 97精品国产自在现线免费观看 | 精品在线看 | 青草草在线观看 | 成年美女黄网色大观看全 | 国产精品福利在线观看免费不卡 | 国产欧美一区二区三区免费看 | 四虎永久在线精品免费影视 | 麻豆找网服 | 日本免费不卡在线一区二区三区 | 性xx色3d动画xx无尽 | 国产xxx在线 | 白发在线视频播放观看免费 | 国产亚洲人成网站在线观看不卡 | 国产精品不卡高清在线观看 | 青青青草国产 | 欧美在线播放一区二区 | 成人榴莲视频 | 我们中文在线观看免费完整版 | 国产99页| 91香蕉视频导航 | 牛牛在线观看 | 蜜桃在线| 好吊操这里有精品 | 免费视频完整版在线观看网站 | 国产精品2 |