Redis学习笔记(一)——事务处理

事务处理

multi      · · · · · ·  开启事务

incr key1  incr key2  ...  incr keyn     · · · · · ·  将元素放入队列

exec     · · · · · ·  执行事务

discard       · · · · · ·  清空事务队列,放弃执行

用法

MULTI 命令用于开启一个事务,它总是返回 OK 。

MULTI 执行之后, 客户端可以继续向服务器发送任意多条命令, 这些命令不会立即被执行, 而是被放到一个队列中, 

当 EXEC命令被调用时, 所有队列中的命令才会被执行。

另一方面, 通过调用 DISCARD , 客户端可以清空事务队列, 并放弃执行事务。


JavaApi

    Transaction tx = getJedis().multi();

    long start = System.currentTimeMillis();

    System.out.println(start);

    for(int i = 0; i < 10000;i ++){

            tx.set("t"+1, "t"+1);

    }

    tx.exec();

    System.out.println(System.currentTimeMillis() - start);

    getJedis().disconnect();


事务概念

  • 事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。

  • 事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行。


事务错误

  • 事务在执行 EXEC 之前,入队的命令可能会出错。比如说,命令可能会产生语法错误(参数数量错误,参数名错误,等等),或者其他更严重的错误,比如内存不足(如果服务器使用 maxmemory 设置了最大内存限制的话)。

  • 命令可能在 EXEC 调用之后失败。举个例子,事务中的命令可能处理了错误类型的键,比如将列表命令用在了字符串键上面,诸如此类。

     

不支持回滚事务(RollBack)

  • Redis 命令只会因为错误的语法而失败(并且这些问题不能在入队时发现),或是命令用在了错误类型的键上面:这也就是说,从实用性的角度来说,失败的命令是由编程错误造成的,而这些错误应该在开发的过程中被发现,而不应该出现在生产环境中。

  • 因为不需要对回滚进行支持,所以 Redis 的内部可以保持简单且快速


check-and-set 操作实现乐观锁

        WATCH 命令可以为 Redis 事务提供 check-and-set (CAS)行为。被 WATCH 的键会被监视,并会发觉这些键是否被改动过了。 如果有至少一个被监视的键在 EXEC 执行之前被修改了, 那么整个事务都会被取消, EXEC 返回nil-reply来表示事务已经失败。

watch作用

     如果在 WATCH 执行之后, EXEC 执行之前, 有其他客户端修改了 mykey 的值, 那么当前客户端的事务就会失败。 程序需要做的, 就是不断重试这个操作, 直到没有发生碰撞为止。

这种形式的锁被称作乐观锁, 它是一种非常强大的锁机制。 并且因为大多数情况下, 不同的客户端会访问不同的键, 碰撞的情况一般都很少, 所以通常并不需要进行重试。

WATCH mykey

val = GET mykey

val = val + 1

MULTI

SET mykey $val

EXEC

    如果在 WATCH 执行之后, EXEC 执行之前, 有其他客户端修改了 mykey 的值, 那么当前客户端的事务就会失败。 程序需要做的, 就是不断重试这个操作, 直到没有发生碰撞为止。    

    这种形式的锁被称作乐观锁, 它是一种非常强大的锁机制。 并且因为大多数情况下, 不同的客户端会访问不同的键, 碰撞的情况一般都很少, 所以通常并不需要进行重试。

监视

    WATCH 命令可以被调用多次。 对键的监视从 WATCH 执行之后开始生效, 直到调用 EXEC 为止。

    可以在单个 WATCH 命令中监视任意多个键

关闭监视

    自动性取消:当 EXEC 被调用时, 不管事务是否成功执行, 对所有键的监视都会被取消。

    默认性取消:当客户端断开连接时, 该客户端对键的监视也会被取消。

    强制性取消:使用无参数的 UNWATCH 命令可以手动取消对所有键的监视。 对于一些需要改动多个键的事务, 有时候程序需要同时对多个键进行加锁, 然后检查这些键的当前值是否符合程序的要求。 当值达不到要求时, 就可以使用 UNWATCH 命令来取消目前对键的监视, 中途放弃这个事务, 并等待事务的下次尝试



JavaApi

    getJedis().set("likeCount", "0");

    getJedis().watch("likeCount");

    int likeCount = Integer.parseInt(getJedis().get("likeCount"));

    getJedis().multi();

    for(int i = 1; i < 10; i ++){

    likeCount = likeCount + i;

    getJedis().set("likeCount", String.valueOf(likeCount));

    }

    getJedis().multi().exec();

    System.out.println(getJedis().get("likeCount"));













评论

© dzxlovelar | Powered by LOFTER