资讯专栏INFORMATION COLUMN

聊聊redis的事务操作

luckyw / 2598人阅读

摘要:序本文主要研究一下的事务操作命令与命令行实例部分执行命令行实例与命令行实例需要有才可以执行,成功返回小结提供指令,类似,不过遇到类型操作等错误时不会滚,该成功执行的命令还是成功执行,该失败的还是失败保证的是,只要命令有执行成功,则事务中一系

本文主要研究一下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 connection = client.connect();
        RedisCommands 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 connection = client.connect();
        RedisCommands 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 connection = client.connect();
        RedisCommands 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 connection = client.connect();
        RedisCommands syncCommands = connection.sync();

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

        //another connection
        StatefulRedisConnection conn2 = client.connect();
        RedisCommands 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事务

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/36855.html

相关文章

  • Redis学习笔记

    摘要:目前供职于公司。哈希是从版本之后才有的数据结构。我们来看一个例子代码如下建立哈希并赋值列出哈希的内容更改中的某一个值再次列出哈希的内容发现,密码已经被更改了。 【redis是什么】 redis是一个开源的、使用C语言编写的,支持网络交互的、可基于内存也可持久化的key-value数据库。 redis的官网地址,非常好记,是redis.io。(特意查了一下,域名后缀io属于国家域名,是b...

    宋华 评论0 收藏0
  • 关于 Redis 闲扯

    摘要:刚换工作不久,这段时间主要的工作就是开发,用了很多。自身的特色所有操作均为原子操作,即不可分割操作。通常为单进程,内部为队列实现,但是由于直接操作内存,所以很快。支持多种数据结构相对。同时还支持这样的事务。 刚换工作不久,这段时间主要的工作就是开发 Nodejs,用了很多 redis。随便聊聊 Redis 一些使用经验,如果有不妥或者错误之处,欢迎指正。 Redis 自身的特色: ...

    546669204 评论0 收藏0
  • Java面试通关要点汇总集

    摘要:本文会以引出问题为主,后面有时间的话,笔者陆续会抽些重要的知识点进行详细的剖析与解答。敬请关注服务端思维微信公众号,获取最新文章。 原文地址:梁桂钊的博客博客地址:http://blog.720ui.com 这里,笔者结合自己过往的面试经验,整理了一些核心的知识清单,帮助读者更好地回顾与复习 Java 服务端核心技术。本文会以引出问题为主,后面有时间的话,笔者陆续会抽些重要的知识点进...

    gougoujiang 评论0 收藏0
  • SegmentFault 技术周刊 Vol.37 - 分布式缓存利器:Redis

    摘要:持久化到中反向代理的负载均衡基于的集群搭建如何实现从中订阅消息转发到客户端的扩展是阻塞式,使用订阅发布模式时,会导致整个进程进入阻塞。缓存是用于解决高并发场景下系统的性能及稳定性问题的银弹。 showImg(https://segmentfault.com/img/bVYE6k?w=900&h=385); Redis 是由意大利程序员 Salvatore Sanfilippo(昵称:a...

    kuangcaibao 评论0 收藏0
  • SegmentFault 技术周刊 Vol.37 - 分布式缓存利器:Redis

    摘要:持久化到中反向代理的负载均衡基于的集群搭建如何实现从中订阅消息转发到客户端的扩展是阻塞式,使用订阅发布模式时,会导致整个进程进入阻塞。缓存是用于解决高并发场景下系统的性能及稳定性问题的银弹。 showImg(https://segmentfault.com/img/bVYE6k?w=900&h=385); Redis 是由意大利程序员 Salvatore Sanfilippo(昵称:a...

    binaryTree 评论0 收藏0

发表评论

0条评论

luckyw

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<