美文网首页Redis
聊聊redis的事务操作

聊聊redis的事务操作

作者: go4it | 来源:发表于2018-09-19 15:27 被阅读12次

本文主要研究一下redis的事务操作

命令

multi与exec

  • 命令行
127.0.0.1:6379> multi
OK
127.0.0.1:6379> incr total
QUEUED
127.0.0.1:6379> incr len
QUEUED
127.0.0.1:6379> exec
1) (integer) 2
2) (integer) 2
127.0.0.1:6379> get total
"2"
127.0.0.1:6379> get len
"2"
  • lettuce实例
    @Test
    public void testMultiExec(){
        RedisClient client = RedisClient.create("redis://192.168.99.100:6379/0");
        StatefulRedisConnection<String, String> connection = client.connect();
        RedisCommands<String, String> syncCommands = connection.sync();

        syncCommands.set("hello","1");
        syncCommands.set("world","2");

        syncCommands.multi();
        syncCommands.incr("hello");
        syncCommands.incr("world");

        //DefaultTransactionResult[wasRolledBack=false,result=[1, 2, 1, 3, 1]]
        TransactionResult transactionResult = syncCommands.exec();
        System.out.println(transactionResult);
        System.out.println(syncCommands.get("hello"));
        System.out.println(syncCommands.get("world"));
    }

部分执行

  • 命令行
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set a hello
QUEUED
127.0.0.1:6379> set b world
QUEUED
127.0.0.1:6379> incr a
QUEUED
127.0.0.1:6379> set c part
QUEUED
127.0.0.1:6379> exec
1) OK
2) OK
3) (error) ERR value is not an integer or out of range
4) OK
127.0.0.1:6379> get a
"hello"
127.0.0.1:6379> get b
"world"
127.0.0.1:6379> get c
"part"
  • lettuce实例
    @Test
    public void testMultiExecError(){
        RedisClient client = RedisClient.create("redis://192.168.99.100:6379/0");
        StatefulRedisConnection<String, String> connection = client.connect();
        RedisCommands<String, String> syncCommands = connection.sync();

        syncCommands.multi();
        syncCommands.set("a","hello");
        syncCommands.set("b","world");
        syncCommands.incr("a");
        syncCommands.set("c","part");
        //DefaultTransactionResult[wasRolledBack=false,result=[OK, OK, io.lettuce.core.RedisCommandExecutionException: ERR value is not an integer or out of range, OK, 1]]
        TransactionResult transactionResult = syncCommands.exec();
        System.out.println(transactionResult);
        System.out.println(syncCommands.get("a"));
        System.out.println(syncCommands.get("b"));
        System.out.println(syncCommands.get("c"));
    }

multi与discard

  • 命令行
127.0.0.1:6379> set sum 1
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> incr sum
QUEUED
127.0.0.1:6379> discard
OK
127.0.0.1:6379> get sum
"1"
  • lettuce实例
    @Test
    public void testMultiDiscard(){
        RedisClient client = RedisClient.create("redis://192.168.99.100:6379/0");
        StatefulRedisConnection<String, String> connection = client.connect();
        RedisCommands<String, String> syncCommands = connection.sync();
        syncCommands.incr("key1");
        syncCommands.multi();
        syncCommands.incr("key1");
        //需要有multi才可以执行discard,成功返回OK
        String result = syncCommands.discard();
        System.out.println(result);
        System.out.println(syncCommands.get("key1"));
    }

check and set

    @Test
    public void testWatch(){
        RedisClient client = RedisClient.create("redis://192.168.99.100:6379/0");
        StatefulRedisConnection<String, String> connection = client.connect();
        RedisCommands<String, String> syncCommands = connection.sync();

        String key = "key";
        syncCommands.watch(key);

        //another connection
        StatefulRedisConnection<String, String> conn2 = client.connect();
        RedisCommands<String, String> syncCommands2 = conn2.sync();
        syncCommands2.set(key, "a");

        syncCommands.multi();
        syncCommands.append(key, "b");
        //DefaultTransactionResult [wasRolledBack=true, responses=0]
        TransactionResult transactionResult = syncCommands.exec();
        System.out.println(transactionResult);

        System.out.println(syncCommands.get(key));
    }

小结

  • reids提供multi exec/discard指令,类似open commit/rollback transaction,不过exec遇到类型操作等错误时不会滚,该成功执行的命令还是成功执行,该失败的还是失败
  • multi exec保证的是,只要exec命令有执行成功,则事务中一系列的命令都能执行,如果exec因为网络等问题,server端没有接收到,则事务中的一系列命令都不会被执行
  • discard需要在有调用multi的前提下才能使用,该命令会清空事务队列等待执行的命令
  • redis提供watch指令,可以配合multi exec来使用,可以实现类似数据库的乐观锁的机制,一旦watch的key被其他client有更新,则整个exec操作失败

doc

相关文章

  • 聊聊redis的事务操作

    序 本文主要研究一下redis的事务操作 命令 multi与exec 命令行 lettuce实例 部分执行 命令行...

  • redis的事务控制

    redis的事务控制。 问个最简单的问题:redis有事务吗? 答:有。 再问个问题:redis事务能保证操作的原...

  • go redis

    go 操作redis操作 Pipelining(管道) 发布/订阅 事务

  • redis事务

    redis事务命令 案例1 - 正常执行事务 1.开启事务 2.事务内包含的所有操作,此时redis会将以下的所有...

  • Redis事务

    Redis事务的三个阶段 开启事务 命令入队列 执行事务 Redis事务的三个特性 单独的隔离操作:事务中所有命令...

  • 黑猴子的家:Redis 事务

    1、Redis的事务定义 (1)Redis事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务...

  • Redis 事务操作原理

    事务原理剖析 redis事务操作,原理是基于pipe队列实现原子性提交操作,在只想事务操作,相当于将需要提交的命令...

  • 八、Redis_事务_锁机制

    1、redis的事务定义 Redis事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行...

  • Redis--事务,锁机制,Redis和Memcached的区别

    Redis事务的定义 Redis事务是一个单独的隔离操作:事务中的所有命令都会序列化,按顺序地执行。事务在执行过程...

  • Redis 事务操作

    重新配置RedisTemplate 并设置 开启事务 操作Redis存入数据 使用事务watch multi e...

网友评论

    本文标题:聊聊redis的事务操作

    本文链接:https://www.haomeiwen.com/subject/yyyinftx.html