gpt4 book ai didi

ruby - 将 Redis 事务包装在数据库事务中

转载 作者:行者123 更新时间:2023-11-29 13:07:56 24 4
gpt4 key购买 nike

我正在尝试提取存储在 redis 队列中的一堆记录,并将它们以 1000 条为一批写入数据库。

想法是将一个 Redis 事务包装在一个数据库事务中,这样万一 db 提交失败,redis 事务也会爆炸,这样我 lpop 的元素就不会消失,这是一个简单的10 条记录的示例:

  REDIS.with do |redis|
redis.multi do |multi|
MyRailsModel.transaction do
10.times do
attrs = JSON.parse(multi.lpop("foo"))
MyRailsModel.create(attrs)
end
end
end
end

该示例使用 ActiveRecord 约定,但适用于任何设置。

我遇到的问题是 multi.lpop("foo") 并没有真正返回一个值,而是一个 Redis::Future - 如果我尝试简单地put SON.parse(multi.lpop("foo").value) 我得到一个 Redis::FutureNotReady: Value will be available once the pipeline executes. 错误。

我开始从 Redis api 中感觉到我正在尝试做的事情可能不可行,但我发现很难相信一些如此基本的事情,例如在 Redis 交易中不可能获得值(value),所以我希望有人知道我遗漏了什么

最佳答案

Redis 中的事务与 Postgres 中的事务非常不同。来自Redis docs :

A Redis transaction is entered using the MULTI command. The command always replies with OK. At this point the user can issue multiple commands. Instead of executing these commands, Redis will queue them. All the commands are executed once EXEC is called.

因此,在您执行 EXEC 之前,Redis 事务实际上什么也没有发生,此时它会立即运行所有内容,您无法在命令之间进行干预。

这些不是ACID交易;他们提供 isolation , 但不是 atomicity .没有办法回滚更改,更糟糕的是:

even when a command fails, all the other commands in the queue are processed – Redis will not stop the processing of commands.

(当然,这一切都有一个很好的理由:Redis 是单线程的,所以命令被隔离只是因为它们从不并行运行,而“事务”只不过是保证你的命令 block 不会与其他任何人交错。当然,它希望尽可能快地执行该 block ,并且不会浪费时间等待返回客户端的往返行程,或将所有数据版本化到满足偶尔的回滚。)


Redis 并没有真正提供像 ACID 事务这样的高级抽象,它提供了一组低级的 commands您可以(希望)将其组合起来以满足您的需求。如果您需要任务队列的回滚功能,感兴趣的主要命令是 RPOPLPUSH :

Atomically returns and removes the last element (tail) of the list stored at source, and pushes the element at the first element (head) of the list stored at destination.

文档实际上详细说明了这个问题的解决方案(“可靠队列”)。基本上,您可以使用 RPOPLPUSH 将项目(原子地)移动到辅助“进行中”列表中,在处理完后删除它们,并监视列表中的孤立项目,可能会在之后重新排队一些超时(或使用其他检测死处理器的方法)。

如果你不想自己去解决所有这些麻烦,这里有 a million message queue implementations在那里,他们中的许多人在 Redis 之上运行。

关于ruby - 将 Redis 事务包装在数据库事务中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58756152/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com