Redis 事物与Lua基础知识 (十)

为了保证多条命令组合的原子性,Redis提供了简单的事务功能以及集成Lua脚本来解决这个问题。

Redis提供了简单的事务功能,将一组需要一起执行的命令放在multi和exec两个命令之间。multi命令代表事务开始,exec命令代表事务结束,它们之间的命令是原子顺序执行的。

127.0.0.1:6379> multi
OK
127.0.0.1:6379> sadd user:a:follow user:b
QUEUED
127.0.0.1:6379> sadd user:b:fans user:a
QUEUED
127.0.0.1:6379> exec
1) (integer) 1
2) (integer) 1
127.0.0.1:6379> 

可以看到,sadd命令此时返回的结果是QUEUED,代表命令并没有真正执行,而是暂时保存在redis中,如果此时另一个客户端在exec之前执行sismember user:a:follow user:b 返回的结果应该是0;当执行exec之后,这两个命令才算完成执行。

如果要停止事务的执行,可以使用discard命令代替exec命令即可。

如果事务中出现命令错误,Redis的处理机制也不尽相同

1、命令错误:例如将set错写成sett,属于语法错误,会造成整个事务无法执行。

2、运行时错误:如用户b在添加粉丝列表时,误把sadd命令写成了zadd命令,这种就是运行时命令错误,因为语法正确。

127.0.0.1:6379> multi
OK
127.0.0.1:6379> sadd sadd user:a:follow user:b
QUEUED
127.0.0.1:6379> zadd user:b:fans 1 user:a
QUEUED
127.0.0.1:6379> exec
1) (integer) 2
2) (error) WRONGTYPE Operation against a key holding the wrong kind of value
127.0.0.1:6379> 

可以看到,Redis并不支持回滚功能,第一个命令已经执行完毕,开发人员需要自己修复这类问题 。

乐观锁

有些应用场景需要在事务之前,确保事务中的key没有被其他客户端修改过,才执行事务,否则不执行(类似乐观锁),Redis提供了watch命令来解决这里问题

//客户端一
127.0.0.1:6379> set testvalue leguan
OK
127.0.0.1:6379> get testvalue
"leguan"
127.0.0.1:6379> watch testvalue
OK


//客户端二
127.0.0.1:6379> append testvalue haha
(integer) 10
127.0.0.1:6379> get testvalue
"leguanhaha"
127.0.0.1:6379>

//客户端一
127.0.0.1:6379> multi
OK
127.0.0.1:6379> append testvalue hehe
QUEUED
127.0.0.1:6379> exec
(nil)
127.0.0.1:6379> get testvalue
"leguanhaha"
127.0.0.1:6379> 

可以看出,当客户端一在multi之前执行了watch命令后,客户端2对key进行了修改,当客户端1再进行修改key值时,exec结果为nil,即事务没有执行。

之所以说Redis提供了简单的事务,是因为它不支持事务的回滚特效,同时无法实现命令的逻辑关系计算。

Lua用法简述

Lua语言

1、Lua数据类型及逻辑处理

Lua语言提供了几种数据结构

booleans(布尔)

numbers(数值)

strings(字符串)

tables(表格)

1)定义字符串: local  strings val="world"

其中,local代表val是一个局部变量,如果没有local代表是全局变量。print函数可以打印出变量的值,“--”是Lua语言的注释

--结果为“world”

print(hello)

2)数组

在Lua中,如果要使用类似数组的功能,可以用tables类型,下面代码定义了一个tables类型的变量myArray,但和大多数编程语言不同的是,Lua的数组下标从1开始计算。

local  tables myArray = {"redis","jedis",true,88.0}

--输出结果:true

print(myArray[3])

如果想遍历这个数组,可以使用for或者while,

a) for

关键字for以end为结束符

local int sum=0 

for i=1,100

do 

     sum = sum + 1

end 

--输出结果为5050

print(sum)

要遍历myArray,首先需要知道tables的长度,只需要在变量前加一个#号即可。

for i=1,#myArray

do 

    print(myArray[i])

end 

除此之外,Lua还提供了内置函数ipairs,使用for index,value ipairs(tables)可以遍历所有的索引下标和值:

for index,value in ipairs(myArray)

do 
  
  print(index)
  
  print(value)

end

b)while

下面代码同样会计算1到100的和,只不过使用的是while循环,while循环同样以end作为结束符

local int sum=9

local int i = 0

while i <= 100

do 

   sum = sum + i

    i = i + 1

end 

--输出结果为5050

print(sum)

c) if   else

要确定数组中是否包含了jedis,有则打印true,注意if以end结尾,if后紧跟then

local tables myArray = {"redis","jedis",true,88.0}

for i=1 ,#myArray

    do 

          if  myArray[i] == "jedis"

             then  

                   print("true")

                   break

         else 

             --do  nothing

            end 

    end

3)哈希

    1、如果要使用类似哈希的功能,同样可以使用tables类型,例如下面tables,每个元素包含了key和value,其中strings1  .. strings2是将两个字符串进行连接

local  tables  user_1={age=28,name="tome"}

--user_1 age is 28

print("user_1 age is " . . user_1["age"])

如果要遍历user_1,可以使用Lua的内置函数pairs

for   key,value  in pairs(user_1)

do  print(key . . value)

end 

2、函数定义

在Lua中,函数以function开头,以end结尾,funcName是函数名,中间部分是函数体

function   funcName()

  ...

end

contact  函数将两个字符串拼接

function  contact (str1,str2)

  return  str1 .. str2

end 

-- "hello world"

print(contact("hello","world"))

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

三丶竹

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

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

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

打赏作者

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

抵扣说明:

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

余额充值