Redis中的事务与Lua脚本

本文深入探讨Redis中事务的实现方式,包括multi和exec命令的使用,以及Lua脚本在事务处理中的优势。同时介绍了Lua脚本的编写方法,如变量定义、条件判断、循环和函数等基本语法,并展示了如何在Java中执行Lua脚本。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文涉及:Redis中普通事务的实现方式、lua脚本的基础使用以及与Java的结合使用

普通事务

Redis本身提供了multi关键字用来开启事务,exec用来关闭事务。Redis这两个关键字之间的操作是原子性的。

127.0.0.1:6379> multi 	
OK	
127.0.0.1:6379> set key 1	
QUEUED	
127.0.0.1:6379> set key2 1	
QUEUED	
127.0.0.1:6379> get key	
QUEUED	
127.0.0.1:6379> exec	
1) OK	
2) OK	
3) "1"

普通事务的错误处理机制

命令错误时整个事务全部失败

127.0.0.1:6379> get key	
"1"	
127.0.0.1:6379> get key2	
"1"	

	
127.0.0.1:6379> multi 	
OK	
127.0.0.1:6379> sets key 3	
(error) ERR unknown command `sets`, with args beginning with: `key`, `3`, 	
127.0.0.1:6379> set key2 3	
QUEUED	
127.0.0.1:6379> exec	
(error) EXECABORT Transaction discarded because of previous errors.	

	
127.0.0.1:6379> get key	
"1"	
127.0.0.1:6379> get key2	
"1"

如果语法没有错误,则只会错误的语句受到影响

127.0.0.1:6379> get key	
"1"	
127.0.0.1:6379> get key2	
"1"	

	
127.0.0.1:6379> multi 	
OK	
127.0.0.1:6379> set key 2	
QUEUED	
127.0.0.1:6379> set key2 2 2 	
QUEUED	
127.0.0.1:6379> exec	
1) OK	
2) (error) ERR syntax error	

	
127.0.0.1:6379> get key	
"2"	
127.0.0.1:6379> get key2	
"1"

为什么要使用Lua脚本

  • ·Lua脚本在Redis中是原子执行的,执行过程中间不会插入其他命令

  • ·Lua脚本可以帮助开发和运维人员创造出自己定制的命令,并可以将这些命令常驻在Redis内存中,实现复用的效果

  • ·Lua脚本可以将多条命令一次性打包,有效地减少网络开销

Lua脚本怎么写

  1. 创建lua脚本

  2. –-注释

  3. 打印语句

print("Hello World!")

   4. 常见数据类型

  • boolean、number、string、nil(这个就是我们平常见的null)

  • 一些小的细节问题:

    • type() 用于查看变量的数据类型,比如print(type(10.4*3)) --> number

    •  判断一个变量是否为空时应该使用" a"==“nil"而不是” a"==nil

    • · lua中"1"+“1” 不是合并字符串成ab而是等于2,想要进行字符串拼接需要"1"…“1” -->11

    •  lua查看字符串长度应该这样来print(#“Hello”) -->5

    • lua中比较不等于的时候要这样比较:a~= b

    •  lua中逻辑运算符是and、or、not

5. 变量

a = 5               -- 全局变量	
local b = 5         -- 局部变量

6. 条件判断

if maxValue > limit then	
          value = limit;	
      else if	
          value = maxValue;	
      else 	
          value = 0;	
      end

7. 循环

for i, v in ipairs(a) do	
    print(i, v)      --i是索引,且是从1开始的。v就是value了。	
end

8. 函数

nction test(n)	
    if n == 0 then	
        return 1	
    else	
        return -1	
    end	
end

看完以上几条你的基础其实已经过关了,如果仅仅在操作redis上的话就已经够了。

Redis与Lua脚本

  1. 在脚本中与redis进行交互:

local value = redis.call('GET',key);	
redis.call('SET',key,value+2);	
redis.call('DECR',key);	
redis.call('EXPIRE',key,10);

    redis.call命令就是在lua中调用redis的相关命令,第一个参数放入要执行的命令,后面的参数放入命令需要的参数就ok了。

    2.  Redis如何执行Lua脚本:

redis-cli --eval redis-ratelimiter-counter.lua key limit , value1 value2

上方这段命令的意思呢,其实就是告诉redis:请你启动客户端的时候帮我执行一下redis-ratelimiter-counter.lua这个文件,然后呢,执行文件的话有这么几个参数,key、limit 、 value1、value2细心小伙伴可能会有疑问了,为什么传了4个参数只有一个逗号其他都是空格隔开呢。我们来看一下他们分别是怎么获取的就明白了

local key = KEYS[1];	
local limit = KEYS[2];	

	
local value1 = ARGV[1];	
local value2 = ARGV[2];

这样的话你是不是看明白了呢,逗号前后的参数是两种不同的传值方式而已。

  1. 如何在Java程序中执行lua呢

       @Autowired	
       private RedisTemplate redisTemplate;	
       public void counterConsume(String key, String limit, String lrefreshInterval) {	
         DefaultRedisScript<Long> consumeRedisScript=new DefaultRedisScript();	
           consumeRedisScript.setResultType(Long.class);	
           consumeRedisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("script/redis-ratelimiter-tokenBucket.lua")));//加载lua脚本文件	
           List<Object> keyList = new ArrayList();	
           keyList.add(key);//通过KEYS[1]取值	
           keyList.add(limit);//通过KEYS[2]取值	
           List<Object> argvList = new ArrayList();	
           argvList.add(lrefreshInterval);//通过ARGV[1]取值	
           String result=redisTemplate.execute(redisScript,keyList,argvList).toString();	
       }

 

点击下方“阅读原文”查看本文使用Lua脚本的源码!!!

640?wx_fmt=jpeg

万水千山总是情,点个 “在看” 行不行!!!

640?wx_fmt=png 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值