https://www.workerman.net/doc/webman/db/redis.html 中只有 pipeline 的使用方法, 如果想使用事务保证操作的原子性,该怎么用呢?
无法启用
$key = 'Dingding_send_message'; $contents = Redis::eval(<<<'LUA' local content = redis.call("get", KEYS[1]) redis.call("del", KEYS[1]) return content LUA, 1, $key);
这不是事务,只是一个原子性的指令,ACID 特性只保证了 A。
ACID
A
而且 Redis 官方在 7.0 之后推出了 Functions 替代 Eval Scripts.
Redis
7.0
Functions
Eval Scripts
嗯。实际上我只要保证在读取和删除之间不要插入新的数据就行。这个可以满足我的要求。
可以尝试编写lua脚本
请教怎么做?
你看下这个:https://www.tkcnn.com/redis/commands/Eval.html
谢谢,好像这样可以: $key = 'Dingding_send_message'; $contents = Redis::eval(<<<'LUA' local content = redis.call("get", KEYS[1]) redis.call("del", KEYS[1]) return content LUA, 1, $key);
场景是这样的: 有多个redis消费队列同时运行,接受一个字符串$msg,我需要把$msg存到Redis里,如果之前已经存了,就append。 另一个自定义进程,每5分钟运行一次,检查Redis中的字符串是否存在,如存在则将$msg通过钉钉发出去,同时在Redis中删除字符串。 问题是现在没法用Redis事务,我担心自定义进程删除Redis的时候,消费队列正好新增。 这种场景,有更好的解决方案吗?
也可以结合redis list来管理 lpush + rpop
//消息入列 $redis->lPush('Dingding_send_message', $msg); //定时任务进行出列 while ($msg = $redis->rPop('Dingding_send_message')) { sendToDingDing($msg); //发送到钉钉 }
有30个进程在1分钟之内往Redis中放数据,也许其中几个会失败,我大概在1分钟以后,将这30个都拿出来拼成一个字符串发送到钉钉。
用你这种一个个发的话,实际上我就没必要这样做了,收到信息就发掉就行了。
无法启用
这不是事务,只是一个原子性的指令,
ACID
特性只保证了A
。而且
Redis
官方在7.0
之后推出了Functions
替代Eval Scripts
.嗯。实际上我只要保证在读取和删除之间不要插入新的数据就行。这个可以满足我的要求。
可以尝试编写lua脚本
请教怎么做?
你看下这个:https://www.tkcnn.com/redis/commands/Eval.html
谢谢,好像这样可以:
$key = 'Dingding_send_message';
$contents = Redis::eval(<<<'LUA'
local content = redis.call("get", KEYS[1])
redis.call("del", KEYS[1])
return content
LUA, 1, $key);
场景是这样的:
有多个redis消费队列同时运行,接受一个字符串$msg,我需要把$msg存到Redis里,如果之前已经存了,就append。
另一个自定义进程,每5分钟运行一次,检查Redis中的字符串是否存在,如存在则将$msg通过钉钉发出去,同时在Redis中删除字符串。
问题是现在没法用Redis事务,我担心自定义进程删除Redis的时候,消费队列正好新增。
这种场景,有更好的解决方案吗?
也可以结合redis list来管理 lpush + rpop
有30个进程在1分钟之内往Redis中放数据,也许其中几个会失败,我大概在1分钟以后,将这30个都拿出来拼成一个字符串发送到钉钉。
用你这种一个个发的话,实际上我就没必要这样做了,收到信息就发掉就行了。