首页 > 编程语言 >ThinkPHP 实现简单的缓存锁

ThinkPHP 实现简单的缓存锁

时间:2024-04-08 16:29:53浏览次数:14  
标签:缓存 lock key 简单 ThinkPHP LockUtils 锁定 id

使用 ThinkPHP 实现简单的缓存锁

在开发过程中,为了避免重复提交等问题,我们常常需要使用缓存锁来控制并发访问。本文将介绍如何利用 ThinkPHP 框架实现一个简单的缓存锁功能。

锁 Key 的生成

在实现缓存锁之前,首先需要确定锁的唯一标识,这里我们采用了学生 ID 和费用数据 ID 来生成锁的唯一 Key。代码如下:

$lockKey = 'pay:StudentId:' . $this->student_id . 'feeDataId:' . $id;
判断是否已经锁定

在获取锁之前,我们需要先判断当前 Key 是否已经被锁定。如果已经锁定,则需要等待一段时间后再尝试获取锁,这里我们设置等待时间为 30 秒。代码如下:

$lock = LockUtils::isLock($lockKey);
if ($lock) {
    throw new BusinessException(Code::PARAM_ERROR, '请勿重复提交,30秒后再试');
}
锁定

获取锁成功后,我们需要进行锁定操作。这里我们使用了一个自定义的 LockUtils 类来实现锁的操作,其中包括了锁定和判断是否锁定的方法。具体代码如下:

use app\common\utils\LockUtils;

LockUtils::lock($key, int $time = 30): void;
use app\common\utils\LockUtils;

LockUtils::isLock($key): bool;
LockUtils 类的实现

下面是 LockUtils 类的具体实现,它利用了 ThinkPHP 框架的缓存功能来实现锁的操作:

<?php
declare (strict_types=1);

namespace app\common\utils;

use think\facade\Cache;

class LockUtils
{

    /**
     * 锁定
     * @param string $key 锁的唯一标识
     * @param int $time 锁定时长,默认为 30 秒
     * @return void
     */
    public static function lock(string $key, int $time = 30): void
    {
        Cache::set($key, 'lock', $time);
    }

    /**
     * 判断是否锁定
     * @param string $key 锁的唯一标识
     * @return bool
     */
    public static function isLock(string $key): bool
    {
        $lock = Cache::get($key);
        return $lock ? true : false;
    }
}

以上就是利用 ThinkPHP 实现简单的缓存锁的方法。通过合理的使用缓存锁,我们可以有效地控制并发访问,提高系统的稳定性。

下面是有上下文的具体使用的支付提交代码

 $fee = $feeModel->where('id', $feeData->fee_id)
            ->where('status', 1)
            ->find();

        if (!$fee) {
            throw new BusinessException(Code::PARAM_ERROR, '缴费项目不存在/已结束/已取消');
        }

        // 缴费金额 (分)
        $money = $feeData->money * 100;

        if (empty($money) || $money <= 0) {
            throw new BusinessException(Code::PARAM_ERROR, '缴费金额错误');
        }

        // 锁Key
        $lockKey = 'pay:StudentId:' . $this->student_id . 'feeDataId:' . $id;
        // 判断是否已经锁定
        $lock = LockUtils::isLock($lockKey);
        // 已经锁定,则等待30秒
        if ($lock) {
            throw new BusinessException(Code::PARAM_ERROR, '请勿重复提交,30秒后再试');
        }

        // 锁定
        LockUtils::lock($lockKey);

        // 缴费ID
        $fee_data_id = $feeData->id;
        // 订单号
        $order_no = StrUtils::generateTradeNo();

回调接收部分
在这里插入图片描述

标签:缓存,lock,key,简单,ThinkPHP,LockUtils,锁定,id
From: https://blog.csdn.net/weixin_61154364/article/details/137513522

相关文章

  • 简单处理——二值化(钢笔画)和差分化(浮雕画)
    简单处理——二值化(钢笔画)和差分化(浮雕画)一、钢笔画和浮雕画​ RGB转灰度图就类似于英语学习中的abandon,在熟悉了YCbCr等颜色空间以及简单的图像反转之后,我们可以将目光移向今天的主题——二值化和差分化;​ 二值化概念比较简单,就是你给灰度在0—255的灰度图像设置一个阈值,大于......
  • HJ19 简单错误记录
    描述开发一个简单错误记录功能小模块,能够记录出错的代码所在的文件名称和行号。处理:1、记录最多8条错误记录,循环记录,最后只用输出最后出现的八条错误记录。对相同的错误记录只记录一条,但是错误计数增加。最后一个斜杠后面的带后缀名的部分(保留最后16位)和行号完全匹配的记录才......
  • Chrome浏览器前端开发调试时强制更新js、css静态资源文件缓存的方法
    以Chrome浏览器为例,国产浏览器未做全面测试。前端开发静态文件时,浏览器访问会缓存样式、图片、js等,怎么快速更新缓存。以下方法特别适合只想清除某个网页的缓存,而不想清除全部浏览器缓存可以采用以下方法。一、强制刷新同时按住ctrl+f5或ctrl+shift+r进行访问页面强制刷新,一般......
  • Chromium 自定义缓存策略
    目录CefRequestHandler在什么位置实现我如何将本地资源作为该请求资源返回呢?我怎么缓存网络资源呢,比如图片和视频?CefResourceHandler如何实现缓存图片和视频,缓存时间无限长,设置缓存路径?demoMyResourceHandler在哪里设置?ChromiumEmbeddedFramework(CEF)是一个开源库,用于......
  • c语言的数组以及简单函数
    数组与函数的基本定义数组正常数组数组的四要素数组名:本质上就是一个标识符常量元素:同一个数组中的元素数据类型要相同下标:数组的索引可以通过下标查找数组里的某一个值从0开始数组的长:表示元素的数量数组的定义先指定元素类型与个数,后在进行赋值(初始化)intarr[7];......
  • 【知识点】Redis-缓存-缓存击穿
    缓存击穿:缓存中一个热点数据过期或失效时,由于该数据非常受欢迎,会有大量请求直接打到数据库上,导致数据库负载增大、相应变慢甚至瘫痪。解决方式:互斥锁在查询数据库之前首先获取分布式锁,更新redis之后再释放锁,可以保证数据的强一致性。优缺点:优点:强一致性缺点:性能差逻辑......
  • 简单处理——灰度图像反转和彩色图像反转
    简单处理——灰度图像反转和彩色图像反转​ 在前面的简单示例中,我们简单了解了RGB格式的数据,清楚了RGB888、RGB332、RGB565等等,同时进行了简单的灰度处理,将彩色图转换为灰度图,但是我们在实际计算机视觉的处理过程中,还需要对于图像的亮度信息有一个更直观的判断,同时有时候我们也会......
  • HTTP的强制缓存和协商缓存
    HTTP的强制缓存和协商缓存HTTP的缓存技术强制缓存ExpiresCache-Control协商缓存If-Modified-Since和Last-ModifiedIf-None-Match和ETag优先级可被缓存的请求方法总结HTTP的缓存技术  当我们进行HTTP请求时,需要将请求报文发送给对端,当服务端收到请求后会做出合适......
  • Ingress简单使用
    介绍Ingress是Kubernetes中用于公开和管理集群内服务的一种API资源。它充当了集群入口的角色,可以将外部流量路由到集群内部的服务,同时提供了一些高级功能,如负载均衡、TLS终止、虚拟主机路由等。下面是Ingress的一个简单示例,可将所有流量都发送到同一Service:通......
  • Spring Boot数据缓存之Spring缓存抽象 @Cacheable初体验
    在数据缓存之Cache规范JSR107中对Spring的缓存抽象有了一定的了解,下面通过示例实战对其深入探讨。需要注意的是使用Spring缓存抽象时要关注两点:①确定那些方法需要被缓存    ②缓存策略具体案例如下:1、导入依赖Mysql、Mybatis、W......