zoukankan      html  css  js  c++  java
  • redis 事务

    首先 redis 单个命令是原子性的  因为单线程

    Redis客户端对服务端的每次调用都经历了发送命令,执行命令,返回结果三个过程。其中执行命令阶段,由于Redis是单线程来处理命令的,所有到达服务端的命令都不会立刻执行,所有的命令都会进入一个队列中,然后逐个执行,并且多个客户端发送的命令的执行顺序是不确定的,但是可以确定的是不会有两条命令被同时执行,不会产生并发问题,这就是Redis的单线程基本模型。

    关系型数据库 比如 mysql存在隔离级别设置 (默认值:repeatable-read)

     

    1、尽可能使用 已有的命令(原子性) 如 INCR、ZPOPMAX、ZPOPMIN

    2、Lua脚本

    https://redisbook.readthedocs.io/en/latest/feature/scripting.html

    redis lua脚本的好处
    ①减少网络开销。可以将多个请求通过脚本的形式一次发送,减少网络延迟。
    ②原子操作。redis将整个脚本当做一个整体去执行,中间不会被其他命令插入。因此无需担心脚本执行过程中会出现竞态条件
    ③复用。客户端发送的脚本会永久保存在redis中,这样,可以复用这一脚本而不用使用代码完成相同的逻辑。

    3、watch指令

    类似于乐观锁,在事务提交时,如果watch监控的多个KEY中任何KEY的值已经被其他客户端更改,则使用EXEC执行事务时,事务队列将不会被执行,同时返回Nullmulti-bulk应答以通知调用者事务执行失败。

    自动的递增一个key

    如果在同一时间,只有一个客户端在执行上面的操作,那么上面的操作是可靠的。但如果同时有多个用户执行上面的操作的话,那结果就是不可靠的了

    1、INCR命令

    2、我们可以使用 WATCH 来很好的解决这个问题:

    使用以上的代码,当有另一个用户在我们调用WATCH 和 EXEC之间,修改了mykey的值val,那么这个事务就会失败。这种形式的锁称为乐观锁,是一种非常强大的锁。

    WATCH 说明

    WATCH 到底是什么意思呢? 这个命令使得 EXEC 命令的执行必须满足一个条件:如果被WATCH的 keys 没有一个被更改(但它们可以在事务中被修改),则执行事务;不然,就不会执行这个事务。(注意,如果你 WATCH了一个有生命周期的key,并且这个key过期了, EXEC 依然会执行)

    WATCH 可以被多次调用。所有的WATCH 调用都会在 EXEC 调用之前起作用。WATCH可以接收任意多的key 。

    当 EXEC 被调用后, 所有的keys都将UNWATCH,不管这个事务会不会终止。同样,当一个客户端链接关闭后, 该客户端对键的监视也会被取消(UNWATCH)。

    可以使用UNWATCH (没有参数)命令来刷新所有被WATCH的keys。有时会这样操作,我们乐观地锁定了几个keys,因为可能我们需要执行一个事务来修改这些keys,但是在读取了keys的当前内容之后,我们不想继续处理了。那么这个时候,我们就可以调用UNWATCH。

     https://mp.weixin.qq.com/s/8fdBKAyHZrfHmSajXT_dnA

    set(key,1,30,NX)

    这样就可以取代setnx指令

     这个过期时间 

    1 不设置 不行 锁可能得不到释放

    2 设置了  如果你执行很慢 其实你的锁 已经被释放掉了 如果有人抢到了 就出现竞态  还有就是 复杂 耗时 逻辑在加锁前 处理好 数据准备好  尽量避免 超时锁 关闭 

    多条命令  尽可能优先使用lua脚本 省得出乱七八糟的问题

    出现并发的可能性

    还是刚才第二点所描述的场景,虽然我们避免了线程A误删掉key的情况,但是同一时间有A,B两个线程在访问代码块,仍然是不完美的。

    怎么办呢?我们可以让获得锁的线程开启一个守护线程,用来给快要过期的锁“续航”

    当过去了29秒,线程A还没执行完,这时候守护线程会执行expire指令,为这把锁“续命”20秒。守护线程从第29秒开始执行,每20秒执行一次。 

    当线程A执行完任务,会显式关掉守护线程。

    另一种情况,如果节点1 忽然断电,由于线程A和守护线程在同一个进程,守护线程也会停下。这把锁到了超时的时候,没人给它续命,也就自动释放了。

     

    http://doc.redisfans.com/

    https://www.runoob.com/redis/redis-transactions.html

    http://doc.redisfans.com/topic/transaction.html#watch-zpop

    https://baijiahao.baidu.com/s?id=1613631210471699441&wfr=spider&for=pc

  • 相关阅读:
    java入门 (七) 面向对象(三)
    java入门 (七) 面向对象(二)
    java入门 (七) 面向对象(一)
    ajax异步请求,$.each遍历拼接数据
    java入门 (六) 数组(二)
    java入门 (六) 数组(一)
    java入门 (五) 方法
    微信小程序
    776C Molly's Chemicals --- 前缀和
    CF 458C Elections --- 三分|线段树
  • 原文地址:https://www.cnblogs.com/light-train-union/p/12649739.html
Copyright © 2011-2022 走看看