Redis集群事务控制工具

实现原理: redis集群对象JedisCluster不支持事务,但是,集群里面的每个节点支持事务。我们可以把这个key临时插入到集群中的某一个节点上,然后遍历集群的节点,获取临时key所在的那个节点,这样我们就可以开启这个节点的事务,最后删除临时key。

第一步:找到需要set的值插入到哪个节点上(比如set("姓名","张三"),找到"姓名"这个key所要插入的节点),并开启此节点事务。

public static Map<String, Transaction> multi(JedisCluster jedisCluster, String... keys)
  {
    Map<String, Transaction> txMap = new HashMap();
    if ((keys != null) && (keys.length > 0))
    {
      String[] arrayOfString;
      int j = (arrayOfString = keys).length;
      for (int i = 0; i < j; i++)
      {
        String key = arrayOfString[i];

//此时查看集群中是否有这个key的值
        boolean clusterExists = jedisCluster.exists(key).booleanValue();
        if (!clusterExists) {

//如果节点没有此值,那么用这个key作为临时key,插入
          jedisCluster.set(key, "");
        }

//获取集群所有的节点,遍历
        Map<String, JedisPool> mapNodes = jedisCluster.getClusterNodes();
        for (Map.Entry<String, JedisPool> node : mapNodes.entrySet())
        {
          JedisPool pool = (JedisPool)node.getValue();
          Jedis jedis = pool.getResource();
          try
          {

//查看临时key在哪个节点上
            if (jedis.exists(key).booleanValue())
            {
              if (!clusterExists) {

//删除此节点上的临时key
                jedisCluster.del(key);
              }

//把此节点保存并返回
              txMap.put(key, jedis.multi());
            }
          }
          catch (Exception localException) {}
        }
        if (!clusterExists) {
          jedisCluster.del(key);
        }
      }
    }
    return txMap;
  }

第二步:拿到key所在的节点,插入值,并预提交事务

 public static void set(Map<String, Transaction> txMap, Map<String, String> kvMap)
  {
    if (!kvMap.isEmpty()) {
      for (Map.Entry<String, String> entry : kvMap.entrySet())
      {
        String key = (String)entry.getKey();
        String value = (String)entry.getValue();
        
        Transaction tx = (Transaction)txMap.get(key);
        
        tx.set(key, value);
      }
    }
  }

第三步:提交事务并返回结果

 

  public static List<Object> exec(Map<String, Transaction> txMap)
  {
    List<Object> result = new ArrayList();
    if (!txMap.isEmpty()) {
      for (Map.Entry<String, Transaction> entry : txMap.entrySet()) {
        result.addAll(((Transaction)entry.getValue()).exec());
      }
    }
    return result;
  }

 

第四步:测试

public void Test{

public static void main(...){

Map<String,String> kvMapT = new HashMap<>();
        String key1T = "xingm";
        String key2T = "nianl";
        kvMapT.put(key1T, "zhangsan");
        kvMapT.put(key2T, "32");
        //开启事物
        Map<String, Transaction> txMapT = JedisClusterUtil.multi(jedisCluster, key1T,key2T);
        //添加数据  此处为预提交事务   
        JedisClusterUtil.set(txMapT, kvMapT);
        //提交事物  
        JedisClusterUtil.exec(txMapT);

   }

}

结尾:原理就是提前拿key去插入,计算出此key插入到哪个节点,然后开启对应节点的事务并提交。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值