使用laravel解决库存超出的几个方案

数据库字段

使用laravel解决库存超出的几个方案

1. 错误的示范

    /**
     * 错误示范
     * Create by Peter Yang
     * 2021-06-08 10:57:59
     * @return string
     */
    function test1()
    {

        //商品id
        $id = request()->input('id');

        $product = Product::where('id', $id)->firstOrFail();

        if ($product->num <= 0) {

            return "卖光啦!!";
        }

        //库存减1
        $product->decrement('num');

        return "success";

    }

使用 go 模拟并发

package main

import (
    "fmt"
    "github.com/PeterYangs/tools/http"
    "sync"
)

func main() {

    client := http.Client()

    wait := sync.WaitGroup{}

    for i := 0; i < 50; i++ {

        wait.Add(1)

        go func(w *sync.WaitGroup) {

            defer w.Done()

            res, _ := client.Request().GetToString("http://www.api/test1?id=1")

            fmt.Println(res)

        }(&wait)

    }

    wait.Wait()

}

在数据库中查看库存
在这里插入图片描述
库存已超出

2.redis 原子锁

    /**
     * redis原子锁
     * Create by Peter Yang
     * 2021-06-08 11:00:31
     */
    function test2()
    {
        //商品id
        $id = request()->input('id');

        $lock = \Cache::lock("product_" . $id, 10);

        try {

            //最多等待5秒,5秒后未获取到锁,则抛出异常
            $lock->block(5);

            $product = Product::where('id', $id)->firstOrFail();

            if ($product->num <= 0) {

                return "卖光啦!!";
            }
            //库存减1
            $product->decrement('num');

            return 'success';

        }catch (LockTimeoutException $e) {

            return '当前人数过多';

        } finally {

            optional($lock)->release();
        }
    }

库存正常
在这里插入图片描述

3.mysql 悲观锁

    /**
     * mysql悲观锁
     * Create by Peter Yang
     * 2021-06-08 11:00:47
     */
    function test3()
    {

        //商品id
        $id = request()->input('id');

        try {
            \DB::beginTransaction();
            $product = Product::where('id', $id)->lockForUpdate()->first();

            if ($product->num <= 0) {

                return "卖光啦!!";
            }

            //库存减1
            $product->decrement('num');

            \DB::commit();

            return "success";

        } catch (\Exception $exception) {

        }

    }

库存正常

在这里插入图片描述

4.mysql 乐观锁

    /**
     * mysql乐观锁
     * Create by Peter Yang
     * 2021-06-08 11:00:47
     */
    function test4()
    {

        //商品id
        $id = request()->input('id');

        $product = Product::where('id', $id)->first();

        if ($product->num <= 0) {

            return "卖光啦!!";
        }

        //修改前检查库存和之前是否一致,不一致说明已经有变动,则放弃更改
        $res = \DB::update('UPDATE `product` SET num = num -1 WHERE id = ? AND num=?', [$id, $product->num]);

        if (!$res) {

            return '当前人数过多';

        }

        return 'success';


    }

库存正常

使用laravel解决库存超出的几个方案

优化乐观锁

修改库存的 sql 修改为

\DB::update('UPDATE `product` SET num = num -1 WHERE id = ? AND num-1 >= 0', [$id]);

5.redis 存储库存

    /**
     * 库存放在redis
     * Create by Peter Yang
     * 2021-06-15 15:18:31
     * @return string
     */
    function test5()
    {

        //商品id
        $id = request()->input('id');


        $num = Redis::command('get', ['product_' . $id]);


        if ($num <= 0) {

            return "卖完啦!";
        }

        //减库存
        $re = Redis::command('decrby', ['product_' . $id, 1]);


        //减多了回滚
        if ($re < 0) {

            Redis::command('incrby', ['product_' . $id, 1]);


            return "卖完啦!";

        }

        return 'success';

    }
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
好的,以下是一个使用 Laravel 框架编写接口的示例: 1. 首先,在命令行中使用 composer 创建一个新的 Laravel 项目: ``` composer create-project --prefer-dist laravel/laravel your-project-name ``` 2. 创建一个控制器来处理接口请求。在命令行中运行以下命令: ``` php artisan make:controller ApiController ``` 这将在 app/Http/Controllers 目录下创建一个名为 ApiController 的控制器。 3. 在 ApiController 中添加方法来处理接口请求。例如,以下是一个返回所有用户信息的方法: ```php public function getAllUsers() { $users = User::all(); return response()->json($users); } ``` 这个方法将使用 Eloquent ORM 从数据库中获取所有用户,并将其转换为 JSON 格式返回给客户端。 4. 在 routes/api.php 文件中定义路由来调用 ApiController 中的方法。例如,以下是一个调用 getAllUsers 方法的路由: ```php Route::get('/users', 'ApiController@getAllUsers'); ``` 这将在应用程序的 /api/users 路径上创建一个 GET 请求,并将其发送到 ApiController 的 getAllUsers 方法。 5. 运行应用程序并测试接口。在命令行中运行以下命令来启动 Laravel 开发服务器: ``` php artisan serve ``` 现在,您可以使用任何 HTTP 客户端发送请求来测试您的接口。例如,您可以使用 cURL 命令来获取所有用户信息: ``` curl http://localhost:8000/api/users ``` 这应该返回一个包含所有用户信息的 JSON 对象。 希望这个示例可以帮助你开始编写 Laravel 接口。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

叫我峰兄

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值