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

服務(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

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 91大神大战高跟丝袜美女 | 亚洲国产欧美在线人成aaaa20 | 日本xxoo动图网站欧美 | 被老外玩爽的中国美女视频 | 国产成人精品视频午夜 | 亚洲精品动漫在线观看 | 四虎影视e456fcom四虎影视 | 国产乱码免费卡1卡二卡3卡四 | ccc在线在线36 | ass日本乱妇ass | 色综合天天综合网国产人 | 久久热r在线视频精品 | 国产东北三老头伦一肥婆 | 欧美成人v视频免费看 | 日本高清中文字幕一区二区三区 | xxx95日本老师xxx学生 | 国产精品久久久久久久久免费观看 | 男人捅女人漫画 | 青青草在观免费 | 免费国产在线观看 | 欧美视频在线播放观看免费福利资源 | 国产在线视频色综合 | 亚洲国产成人在人网站天堂 | 国产精品视频一区二区三区w | 日韩欧美一区二区三区 | 成人午夜剧场 | 奇米网狠狠网 | 亚洲 欧美 另类 中文 在线 | 天天做天天玩天天爽天天 | 羞羞视频免费观看网站 | 无限在线观看视频大全免费高清 | 国产清纯91天堂在线观看 | 日韩国产欧美精品综合二区 | 国产美女亚洲精品久久久综合91 | 大肥臀风间由美 中文字幕 大东北chinesexxxx露脸 | 成年性午夜免费视频网站不卡 | 花房乱爱在线观看 | 久久久久久久99精品免费观看 | yellow高清免费观看日本 | 女人与d0gxxx | 高清日韩在线 |