欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

基于mysql樂觀鎖實現秒殺的示例代碼

 更新時間:2022年07月01日 09:15:31   作者:yy1209357299  
本文主要介紹了基于mysql樂觀鎖實現秒殺,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

說明

如果你的項目流量非常小,完全不用擔心有并發(fā)的購買請求,那么做這樣一個系統意義不大。但如果你的系統要像12306那樣,接受高并發(fā)訪問和下單的考驗,那么你就需要一套完整的流程保護措施,來保證你系統在用戶流量高峰期不會被搞掛了。

進階redis+mq實現:參考springboot + rabbitmq + redis實現秒殺

嚴格防止超賣
保證用戶體驗:高并發(fā)下,別網頁打不開了,支付不成功了,購物車進不去了,地址改不了了
防止黑產:防止不懷好意的人群通過各種技術手段把你本該下發(fā)給群眾的利益全收入了囊中

具體實現

1、核心
mysql樂觀鎖防止超賣

樂觀鎖是指操作數據庫時(更新操作),想法很樂觀,認為這次的操作不會導致沖突,在操作數據時,并不進行任何其他的特殊處理(也就是不加鎖),而在進行更新后,再去判斷是否有沖突了。

這里是引用通常實現是這樣的:在表中的數據進行操作時(更新),先給數據表加一個版本(version)字段,每操作一次,將那條記錄的版本號加1。也就是先查詢出那條記錄,獲取出version字段,如果要對那條記錄進行操作(更新),則先判斷此刻version的值是否與剛剛查詢出來時的version的值相等,如果相等,則說明這段期間,沒有其他程序對其進行操作,則可以執(zhí)行更新,將version字段的值加1;如果更新時發(fā)現此刻的version值與剛剛獲取出來的version的值不相等,則說明這段期間已經有其他程序對其進行操作了,則不進行更新操作。

2、建表語句
stock商品表

-- ----------------------------
-- Table structure for stock
-- ----------------------------
DROP TABLE IF EXISTS `stock`;
CREATE TABLE `stock` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(50) NOT NULL DEFAULT '' COMMENT '名稱',
  `count` int(11) NOT NULL COMMENT '庫存',
  `sale` int(11) NOT NULL COMMENT '已售',
  `version` int(11) NOT NULL COMMENT '樂觀鎖,版本號',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

初始化數據:

在這里插入圖片描述

stock_order訂單表

-- ----------------------------
-- Table structure for stock_order
-- ----------------------------
DROP TABLE IF EXISTS `stock_order`;
CREATE TABLE `stock_order` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `sid` int(11) NOT NULL COMMENT '庫存ID',
  `name` varchar(30) NOT NULL DEFAULT '' COMMENT '商品名稱',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '創(chuàng)建時間',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

3、業(yè)務流程

在這里插入圖片描述

代碼實現

1、pom

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!--mysql-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.0</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <!--druid-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.10</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.10</version>
        </dependency>

        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>5.2.0</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.8</version>
        </dependency>

        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>5.8.2</version>
            <scope>test</scope>
        </dependency>

2、model

在這里插入圖片描述

可通過逆向工程進行配置,參考idea+mybatis逆向工程

4、dao

public interface StockMapper {

    Stock checkStock(Integer id);//校驗庫存

    int updateSale(Stock stock);//扣除庫存
}
public interface StockOrderMapper {

    //創(chuàng)建訂單
    void createOrder(StockOrder order);
}

5、sql

商品校驗和減庫存

 <select id="checkStock" parameterType="java.lang.Integer" resultType="com.yy.msserver.model.vo.Stock">
    select * from stock where id = #{id}
  </select>

  <update id="updateSale" parameterType="com.yy.msserver.model.vo.Stock" >
    update stock
    set sale = #{sale,jdbcType=INTEGER} + 1,
        version = #{version,jdbcType=INTEGER} + 1,
        count = #{count,jdbcType=INTEGER} - 1
    where id = #{id,jdbcType=INTEGER}
      AND count > 0 AND version = #{version}
  </update>

下訂單

  <insert id="createOrder" parameterType="com.yy.msserver.model.vo.StockOrder">
    insert into stock_order (sid, name,
                             create_time)
    values (#{sid,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR},
            #{createTime,jdbcType=TIMESTAMP})
  </insert>

6、service

public interface StockOrderService {
    public Integer createOrder(Integer id);
}

7、實現

/**
 * @author code
 * @Date 2022/6/24 9:25
 * Description 訂單實現
 * Version 1.0
 */
@Service
public class StockOrderServiceImpl implements StockOrderService {
    @Autowired
    private StockOrderMapper stockOrderMapper;

    @Autowired
    private StockMapper stockMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer createOrder(Integer id) {
        //校驗庫存
        Stock stock = checkStock(id);
        if(stock.getCount()>0){
            System.out.println("當前庫存:" + stock.getCount());
            //扣庫存
            if(updateSale(stock) == 1){
                return createOrder(stock);
            }else {
                return 0;
            }
        }
        return 0;
    }

    //校驗庫存
    private Stock checkStock(Integer id) {
        return stockMapper.checkStock(id);
    }

    //扣庫存
    private int updateSale(Stock stock){
        return stockMapper.updateSale(stock);
    }

    //下訂單
    private Integer createOrder(Stock stock){
        StockOrder order = new StockOrder();
        order.setSid(stock.getId());
        order.setCreateTime(new Date());
        order.setName(stock.getName());
        stockOrderMapper.createOrder(order);
        return order.getId();
    }
}

8、測試
模擬100人參與活動

@SpringBootTest
class MsServerApplicationTests {
    @Autowired
    private StockOrderService stockOrderService;

    @Test
    void contextLoads() throws InterruptedException {

        // 庫存初始化為10,這里通過CountDownLatch和線程池模擬100個并發(fā)
        int threadTotal = 100;

        ExecutorService executorService = Executors.newCachedThreadPool();

        final CountDownLatch countDownLatch = new CountDownLatch(threadTotal);
        for (int i = 0; i < threadTotal ; i++) {
            int uid = i;
            executorService.execute(() -> {
                try {
                    stockOrderService.createOrder(1);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                countDownLatch.countDown();
            });
        }

        countDownLatch.await();
        executorService.shutdown();

    }
}

9、結果

在這里插入圖片描述

商品表

在這里插入圖片描述

訂單表

在這里插入圖片描述

到此這篇關于基于mysql樂觀鎖實現秒殺的示例代碼的文章就介紹到這了,更多相關mysql樂觀鎖秒殺內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 詳解MySQL中WHERE子句的用法

    詳解MySQL中WHERE子句的用法

    這篇文章主要介紹了詳解MySQL中WHERE子句的用法,是MySQL入門學習中的基礎知識,需要的朋友可以參考下
    2015-05-05
  • MySQL 如何修改root用戶的密碼

    MySQL 如何修改root用戶的密碼

    這篇文章主要介紹了MySQL 如何修改root用戶的密碼,幫助大家更好的使用MySQL,不用擔心忘記密碼,感興趣的朋友可以了解下
    2020-09-09
  • mysql數據庫常見基本操作實例分析【創(chuàng)建、查看、修改及刪除數據庫】

    mysql數據庫常見基本操作實例分析【創(chuàng)建、查看、修改及刪除數據庫】

    這篇文章主要介紹了mysql數據庫常見基本操作,結合實例形式分析了mysql創(chuàng)建、查看、修改及刪除數據庫實現方法與操作注意事項,需要的朋友可以參考下
    2020-04-04
  • mysql主從服務器同步心得體會

    mysql主從服務器同步心得體會

    原來看過MYSQL同步數據的實現,可是自己還沒有動過手,今天沒什么事就玩一玩,正好在旁邊有另一臺空電腦,都在同一個路由器下。哈哈,正好。
    2008-06-06
  • MySQL如何確定VARCHAR大小問題

    MySQL如何確定VARCHAR大小問題

    本文主要介紹了MySQL如何確定VARCHAR大小問題,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • VS2019連接mysql8.0數據庫的教程圖文詳解

    VS2019連接mysql8.0數據庫的教程圖文詳解

    這篇文章主要介紹了VS2019連接mysql8.0數據庫的教程,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-05-05
  • 總結幾種MySQL中常見的排名問題

    總結幾種MySQL中常見的排名問題

    這篇文章主要總結了幾種MySQL中常見的排名問題,幫助大家更好的理解和使用MySQL,感興趣的朋友可以了解下
    2020-09-09
  • 快速解決mysql導出scv文件亂碼、躥行的問題

    快速解決mysql導出scv文件亂碼、躥行的問題

    這篇文章主要介紹了快速解決mysql導出scv文件亂碼、躥行的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-07-07
  • MySQL實現批量更新不同表中的數據

    MySQL實現批量更新不同表中的數據

    這篇文章主要介紹了MySQL實現批量更新不同表中的數據,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • MySQL前綴索引導致的慢查詢分析總結

    MySQL前綴索引導致的慢查詢分析總結

    前綴索引,并不是一個萬能藥,他的確可以幫助我們對一個寫過長的字段上建立索引。但也會導致排序(order by ,group by)查詢上都是無法使用前綴索引的
    2013-05-05

最新評論