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

  • 相关阅读:
    UVA 10462 Is There A Second Way Left?(次小生成树&Prim&Kruskal)题解
    POJ 1679 The Unique MST (次小生成树)题解
    POJ 2373 Dividing the Path (单调队列优化DP)题解
    BZOJ 2709 迷宫花园
    BZOJ 1270 雷涛的小猫
    BZOJ 2834 回家的路
    BZOJ 2506 calc
    BZOJ 3124 直径
    BZOJ 4416 阶乘字符串
    BZOJ 3930 选数
  • 原文地址:https://www.cnblogs.com/mushishi/p/14926012.html
Copyright © 2011-2022 走看看