Redis事务

Redis 事务可以一次执行多个命令, 并且带有以下两个重要的保证:

  • 事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
  • 事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行。但中间发生错误不会回滚,错误命令前后的其他命令都会被执行。

一个事务从开始到执行会经历以下三个阶段:

  • 开始事务。
  • 命令入队。
  • 执行事务。

当一个client在一个连接中发出multi命令有,这个连接会进入一个事务上下文,该连接后续的命令并不是立即执行,而是先放到一个队列中。当从此连接受到exec命令后,redis会顺序的执行队列中的所有命令。并将所有命令的运行结果打包到一起返回给client.然后此连接就结束事务上下文。执行discard命令取消事务,放弃执行事务块内的所有命令,结束事务上下文。例子:

    redis> multi
    OK
    redis> incr a
    QUEUED
    redis> incr b
    QUEUED
    redis> exec
    1. (integer) 1
    2. (integer) 1

watch命令
在执行命令的过程中,其他client如果修改这些(被watch的)值,那么exec就会执行失败,返回(nil)即此事务中所有命令执行失败。
例子:在图1watch和exec之间执行图2。


图1
图2

exec,discard,unwatch命令都会清除连接中的所有监视。

jedis例子:

    @Test
    public void jedisTransaction() throws Exception{
        Jedis jedis = JedisUtils.getJedis();
        String watch = jedis.watch("a","b");
        Transaction multi = jedis.multi();

        System.out.println(Thread.currentThread().getId()+"--"+watch);
        //dosomething
        multi.set("a","999");
        multi.set("b","888");
        try {
            Thread.sleep(30000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        List<Object> exec = multi.exec();
        System.out.println("---"+exec);
        jedis.unwatch();
    }

    @Test
    public void jedisTransactionAnotherClient() throws Exception{
        Jedis jedis = JedisUtils.getJedis();
        String watch = jedis.watch("a");
        Transaction multi = jedis.multi();

        System.out.println(Thread.currentThread().getId()+"--"+watch);
        //dosometing
        multi.set("a","777");


        List<Object> exec = multi.exec();
        System.out.println("---"+exec);
        jedis.unwatch();
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • redis事务 Redis 通过 MULTI 、 DISCARD 、 EXEC 和 WATCH 四个命令来实现事务...
    全能程序猿阅读 6,452评论 0 11
  • 1. 概述: 和众多其它数据库一样,Redis作为NoSQL数据库也同样提供了事务机制。在Redis中,MULTI...
    六月星空2011阅读 2,738评论 0 0
  • 在多个客户端同时处理相同的数据时,不谨慎的操作很容易导致数据出错。一般的关系型数据库中有事务保证了数据操作的原子性...
    rainybowe阅读 8,778评论 0 5
  • 关系型数据库的事务具备:原子性、隔离性、持久性、一致性。在Redis中也同样拥有事务的概念,本文主要介绍Redis...
    yingzong阅读 7,055评论 1 5
  • multi开启一个事务,原理是开启客户端属性中的事务开关标示REDIS_MULTI,将客户端从非事务状态切换到事务...
    码农也越野阅读 2,905评论 0 0