zoukankan      html  css  js  c++  java
  • redis不完整的事务实现Transaction

    使用场景

    redis一个命令执行是单线程的,不用担心并发冲突,如果你想有几个命令想像一个命令一样,在这几个命令执行过程中不会执行别的客户端发来的命令 ,也就是原子性,就可以用 redis Transaction

    使用方式

    redis 命令

    multi // 标识事务起始
    command-1
    command-2
    command-3
    exec  // 开始执行 
    

    redis-server 再接收到 exec 命令的时候,才真正开始顺序执行事务里的命令,然后返回全部命令执行结果
    可以用 discard 命令取消事务

    使用 Jedis 执行 Transaction (官方例子)
    jedis的api和原始 redis 命令非常贴近,没有什么学习成本 知道redis command就会用

    Transaction t = jedis.multi();
    t.set("fool", "bar"); 
    Response<String> result1 = t.get("fool");  // 这边的response 现在还是空的, 再exec后才能获取到实际的值
    t.zadd("foo", 1, "barowitch"); 
    t.zadd("foo", 0, "barinsky"); 
    t.zadd("foo", 0, "barikoviev");
    Response<Set<String>> sose = t.zrange("foo", 0, -1);   // get the entire sortedset
    t.exec();                                              // dont forget it 
    
    String foolbar = result1.get();                       // use Response.get() to retrieve things from a Response
    

    使用限制

    1. 不支持事务回滚
      假设命令 a、b、c, a和b执行ok,执行到 c 的时候发生异常了,那么 a和b的操作结果是不会回滚的;

    2. 事务内多个命令间不能相互依赖
      收到 exec 后 redis-server 才开始执行,执行完毕后返回所有结果; 所以事务内多个命令之间不能有依赖,如 command-1 的返回值,不能作为下一个 command-2 的输入,因为此时获取不到结果

    错误示范

    Transaction t = jedis.multi();
    if(t.get("key1").equals("something"))   // exec之前这边是拿不到结果的 
       t.set("key2", "value2");
    else 
       t.set("key", "value");
    
    t.exec();
    

    如果多个命令间有依赖 或者要做异常处理,并且需要原子执行,可以考虑用 script lua 脚本的方式来写

    参考:

    本文来自博客园,作者:mushishi,转载请注明原文链接:https://www.cnblogs.com/mushishi/p/14926012.html

  • 相关阅读:
    201521123028 《Java程序设计》第5周学习总结
    Markdown格式
    201521123028《Java程序设计》第4周学习总结
    201521123028 《Java程序设计》第3周学习总结
    Spring07 JDBC
    Spring06 Aop
    Mystring05 配置文件之间的关系
    Mybatais 13 二级缓存
    Mybatais 14 注释的配置
    Mybatais 12 一级缓存
  • 原文地址:https://www.cnblogs.com/mushishi/p/14926012.html
Copyright © 2011-2022 走看看