Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Transactions 具有读取操作的Redis中的事务_Transactions_Redis_Atomicity - Fatal编程技术网

Transactions 具有读取操作的Redis中的事务

Transactions 具有读取操作的Redis中的事务,transactions,redis,atomicity,Transactions,Redis,Atomicity,使用Redis,我想执行一个命令的原子序列,也就是说,我需要保证在执行序列时,没有其他客户机会在数据库中执行更改 如果我只使用write命令,我可以使用MULTI和EXEC语句来确保使用事务的原子性。但是,我也希望在事务中使用read命令。因此,我不能使用MULTI,因为读取命令也在排队 基本上,以原子的方式,我需要做以下工作: 从数据库中读取x 根据x,将f(x)存储到数据库中 都是1。二,。应该是单个原子事务的一部分 有没有一个简单的方法来解决这个问题?有两个很好的解决方案 选项1: 您需要

使用Redis,我想执行一个命令的原子序列,也就是说,我需要保证在执行序列时,没有其他客户机会在数据库中执行更改

如果我只使用write命令,我可以使用
MULTI
EXEC
语句来确保使用事务的原子性。但是,我也希望在事务中使用read命令。因此,我不能使用
MULTI
,因为读取命令也在排队

基本上,以原子的方式,我需要做以下工作:

  • 从数据库中读取
    x
  • 根据
    x
    ,将
    f(x)
    存储到数据库中
  • 都是1。二,。应该是单个原子事务的一部分


    有没有一个简单的方法来解决这个问题?

    有两个很好的解决方案

    选项1:

    您需要在正在读取的钥匙上发出一个
    手表
    。您的交易将如下所示:

    WATCH x
    x = GET x
    MULTI
    SET y, f(x)
    EXEC
    
    在本例中,多块内的写入命令将以原子方式执行,但如果键
    x
    的值自调用
    WATCH
    以来没有改变,则仅执行。这称为乐观锁。如果
    x
    的值发生变化,应用程序将出现错误,需要决定下一步要做什么,这可能会使用
    x
    的新值重试

    选项2:


    Redis现在支持lua脚本,lua脚本以原子方式执行。如果可以将逻辑封装到lua脚本中,则可以读取密钥,运行
    f(x)
    逻辑,并存储结果,所有这些都是原子化的。根据您执行的逻辑,这可能很棘手,甚至不是一个选项。您甚至可能需要做一些难看的黑客操作,比如将值直接硬编码到您希望redis执行的脚本中,从而将值传递给lua。这就是说,如果你让它工作起来,这种方法应该是可靠的和性能良好的,你不必处理
    EXEC
    失败。

    你可以尝试使用Lua脚本:选项1非常适合我的需要,因为迭代重试操作似乎是一个合理的解决方案。目前,与我提供的示例相比,我的应用程序逻辑要复杂得多,但我肯定会看看Lua。谢谢!