redis lua 抽奖 PHP,通过redis+lua实现加减库存

一. 场景

下单后库存校验或者秒杀场景下,有很多利用“锁”的方案来解决问题。但是加锁其实是一件性价比很低的事,所以我们采用用redis+lua的方式来实现这个功能。

二. 思路

阶段一:

在库存加减逻辑中分为2个步骤:STEP1.读取库存,STEP2.读取库存。

利用其他方法例如"锁"等,也就是想控制好STEP2一定要紧跟STEP1,本质上就是确保获取的库存的最新的数据为最新。

阶段二:

在相对较高的并发场景下,redis被常用作库存管理,我们需要通过最小成本的改动来实现库存的限制。但是redis的读取库存+读取库存一般都是有上层应用代码控制,有没有办法在一个函数调用中能串行执行这俩个步骤了?

阶段三:

众所周知,redis是单线程的,并且现在已经支持lua脚本,那是不是可以利用该组合实现我们的场景了?

三. 设计方案

这个方案就很简单了,直接利用redistemplate执行lua脚本

四. 代码

4.1 lua脚本代码样例

private static final String GET_COUPON_CODE =

"local values = redis.call('hmget',KEYS[1],'recvCnt','couponCnt');\n" + //lua返回value的数组

"if tonumber(values[1]) < tonumber(values[2]) then \n" + //lua的数组索引从1开始 values[1] = recvCnt,values[2] = couponCnt

" redis.call('hincrby',KEYS[1],'recvCnt',1);\n" +

" return true;\n" +

"else\n " +

" return false;\n" +

"end\n";

4.2 redis调用lua脚本

//执行调用

execute(GET_COUPON_CODE, keys);

//此处将数值类型转化为Long

public Long execute(String redisScript,List keys){

RedisScript REDIS_SCRIPT = new DefaultRedisScript<>(redisScript, Long.class);

return redisTemplate.execute(REDIS_SCRIPT,keys);

}

4.3 lua基本用法

redis.call()

redis.pcall()

call与pcall基本上一样。脚本报错时,call会直接报错,pcall不会报错,会把错误信息放到lua table 的err字段中。

五. 说明

1.记得利用“\n”分行,也可以利用string的append拼接

2.values[n]对应有序数组keys,需要控制好各数据顺序

3.lua的数组索引从1开始

六. 总结

我们先分析场景,通过多种方案对比,选用了redis+lua的组合来满足我们的业务需要。利用redis单线程的特点,以及redis2.6版本后开始对lua的支持,我们采用redis执行lua脚本来确保我们查询+修改的串行执行。后面我们展示了code的实现案例,以及介绍了lua脚本的一些注意事项,可以依葫芦画瓢形式自己实现自己的需求。综合而言,我们分析场景应先分析其核心问题,然后利用一些更简洁的方法或小技巧来落地。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/309982.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[设计模式]简单工厂和工厂方法模式适用场景

简单工厂模式 适用场景: 1.工厂类负责创建的对象比较少&#xff0c;由于创建的对象较少&#xff0c;不会造成工厂方法中的业务逻辑太过复杂。 2.客户端只知道传入工厂类的参数&#xff0c;对于如何创建对象并不关心。 工厂方法模式 适用场景: 1.客户端不知道它所需要的对象…

Too Many Segments (easy version) CodeForces - 1249D1(贪心+差分)

题意 给多组线段&#xff0c;而每一个点的覆盖次数不超过K&#xff0c;每次可去除一个线段&#xff0c;问最少去多少线段以及线段的位置。 The only difference between easy and hard versions is constraints. You are given nn segments on the coordinate axis OX. Segme…

c#: 协变和逆变深度解析

环境&#xff1a;window 10.netcore 3.1vs2019 16.5.1一、为什么要有协变&#xff1f;首先看下面的代码&#xff1a;还有下面的&#xff1a;其实上面报错的是同一个问题&#xff0c;就是你无法用List<Fruit>指向List<Apple>&#xff01;我们的疑问在于&#xff0c;…

[设计模式]抽象工厂模式

抽象工厂模式针对的是产品族&#xff0c;而不是产品等级结构。 产品族:同一产地或者同一产商&#xff0c;功能不同。 产品等级:功能相同&#xff0c;产地或者厂商不同。 代码如下: #include <iostream> using namespace std;class AbstractApple { public:virtual vo…

Too Many Segments (hard version) CodeForces - 1249D2(贪心+容器vector+set)

题目 给多组线段&#xff0c;而每一个点的覆盖次数不超过K&#xff0c;每次可去除一个线段&#xff0c;问最少去多少线段以及线段的位置。 The only difference between easy and hard versions is constraints. You are given nn segments on the coordinate axis OX. Segme…

.net core HttpClient 使用之掉坑解析(一)

一、前言在我们开发当中经常需要向特定URL地址发送Http请求操作&#xff0c;在.net core 中对httpClient使用不当会造成灾难性的问题&#xff0c;这篇文章主要来分享.net core中通过IHttpClientFactory 工厂来使用HttpClient的正确打开方式。二、HttpClient使用中的那些坑2.1 错…

linux常用命令 java,Java工程在Linux常用命令

Java Web工程 在Linux下操作常用命令cd ../ 退出当前目录,前往父文件夹cd ezoffice 进入ezoffice文件夹ls 查看目录ps -ef|grep java 查看JAVA进程ps -aux |grep tomcat 查看tomcat进程 的进程号kill -9 12222 杀死ID为12222进程nohup ./startup.sh & 执行startup.sh&…

[设计模式]单例模式(懒汉式,饿汉式)

实现单例步骤: 1.构造函数私有化。 2.增加静态私有的当前类的指针变量。 3.提供静态对外接口&#xff0c;可以让用户获得单例对象。 单例 分为&#xff1a; 1.懒汉式 2.饿汉式 懒汉式 代码如下: class Singleton_lazy { public:static Singleton_lazy *getInstance(){if (pS…

By Elevator or Stairs? CodeForces - 1249E(动态规划)

题意 n层楼&#xff0c;a[i] (0<i<n)表示从 i 楼到 i 1 楼走楼梯的时间&#xff0c;b[i] (0<i<n)表示从 i 楼到 i 1 楼乘电梯的时间&#xff0c;其中每一次乘电梯需要等待 k 时间&#xff0c;楼梯和电梯一次均可上从 x 楼上升到 y 楼 ( y ! x )&#xff0c;即一…

我擦!没想到你们都是这样 “劝退” 员工的!

前几天&#xff0c;我的一个好哥们在微信上跟我吐槽&#xff0c;说这波疫情对经济的影响实在太大了。他说在往年&#xff0c;这个时候跳槽应该开始冒头了&#xff0c;而今年从春节到现在&#xff0c;除了少数几个被裁员之外&#xff0c;200多人的技术团队几乎就没一个主动提离职…

php post nginx 400,Nginx静态文件响应POST请求 提示405错误的解决方法

例1&#xff1a;用linux下的curl命令发送POST请求给Apache服务器上的HTML静态页[rootlocalhost ~]# curl -d 111 https://www.jb51.net/index.html405 Method Not AllowedMethod Not AllowedThe requested method POST is not allowed for the URL /index.html.Apache/1.3.37 S…

Phone List POJ - 3630(字典树模板题)

题意 给定 n个长度不超过 10的数字串&#xff0c;问其中是否存在两个数字串S&#xff0c;T &#xff0c;使得 S是 T的前缀&#xff0c;多组数据。 题目 Given a list of phone numbers, determine if it is consistent in the sense that no number is the prefix of anothe…

开源最大的谎言是什么?

一天前&#xff0c;网友 niksmac 在 Hacker News 上提出了这样一个问题&#xff1a;“开源最大的谎言是什么”&#xff1f;由此引发了诸多讨论。从其他网友的回复来看&#xff0c;他们主要将焦点集中在开源的安全性、使用成本、商业化、开源精神及道德等方面。收到最多回复的网…

唯品会php接口,唯品会链接生成联盟链接 - 唯品会API免费API接口-唯品会API开放API接口-云商数据(www.ecapi.cn)...

{"code":200,"data":{"list":[{"noEvokeUrl":"https://t.vip.com/xxxxx?&wq1","vipQuickAppUrl":"hap://app/com.VIP.VIPQuickAPP/pages/index?targetpages/product/detail&params{"productI…

[设计模式]代理模式

代理模式: 为其他对象提供一种代理以控制对这个对象的访问。 在某些情况下&#xff0c;一个对象不适合或者不能直接引用另一个对象&#xff0c;而代理对象可以在客户端和目标对象之间起到中介的作业。 代码如下: #include <iostream> using namespace std;//共有接口 …

Minimize the Permutation CodeForces - 1256(贪心)

题意&#xff1a; q次询问&#xff0c;每次询问给你长度为n的排列&#xff0c;然后你每次可以选择一个位置i和i1的数字进行交换。但是每个位置只能交换一次&#xff0c;问你反转若干次后&#xff0c;这个排列最小是多少&#xff1f; 题目&#xff1a; You are given a permu…

IO 模型知多少 | 代码篇

引言之前的一篇介绍IO 模型的文章IO 模型知多少 -- 理论篇比较偏理论&#xff0c;很多同学反应不是很好理解。这一篇咱们换一个角度&#xff0c;从代码角度来分析一下。socket 编程基础开始之前&#xff0c;我们先来梳理一下&#xff0c;需要提前了解的几个概念&#xff1a;soc…

[设计模式]外观模式

外观模式:为一组具有类似功能的类群&#xff0c;比如类库&#xff0c;子系统等等&#xff0c;提供一个一致的简单的界面。 代码如下: #include <iostream> using namespace std;class Television { public:void on(){cout << "Tv on" << endl;}v…

Keywords Search HDU - 2222(AC自动机模板)

题意&#xff1a; 给定 n个长度不超过 50的由小写英文字母组成的单词准备查询&#xff0c;以及一篇文章&#xff0c;问&#xff1a;文中出现了多少个待查询的单词。多组数据。 题目&#xff1a; In the modern time, Search engine came into the life of everybody like Go…

php fpm 调试模式,调试 – nginx php-fpm xdebug netbeans只能启动一个调试会话

在过去,我使用apache mod_PHP xdebug netbeans进行开发我的网站(服务器是我的本地机器,运行Debian Squeeze),很高兴 – xdebug工作正常,调试会话可以随时启动和停止,当我需要时它.但是,当我转移到Nginx PHP_fpm xdebug netbeans时,我遇到了一些调试问题.>我的调试会话可能会…