Redis事务处理

事务:ACID

  A:原子性(Atomicity)

  C:一致性(Consistency)

  L:隔离性(lsolation)

  D:持久性(Duravblity)

疑问:在我看到这个Redis事务处理的时候,有一个疑问,既然redis是单线程为啥还存在事务处理问题?

  解答:一个redis实例可以有多个客户端连接访问,当发生需要对某一个key的value进行处理时候,先是拿到这个key,进行相应操作后在set,那么也需要这个过程是一个原子操作,redis对此提供了事务的方案;

 

Redis事务处理流程:

  步骤1:监视keys

     jedis.watch("key1");

  步骤2:开始事务以及事务体

     Transaction transaction = jedis.multi();

     /** 事务体

     */

    List<Object> exec = transaction.exec(); // 事务提交

  步骤3:判断,事务是否提交成功
    exec.isEmpty(); 如果为null,则事务提交失败,可能在事务体中代码出错或者监视的key被本事务之外的对象修改
  步骤4:解除监视
    jedis.unwatch();

public void testRedisTr() {
        jedis.auth("123456");
        jedis.watch("key1");
        Transaction transaction = jedis.multi();
        
        jedis.set("key1", "hello");
        int c = 100/0;
        jedis.set("key2", "word");
        List<Object> exec = transaction.exec();
        if (exec.isEmpty()) {
            System.out.println("事务提交失败");
        }
        jedis.unwatch();

    }

 

使用场景测试代码

/**
     * 事务的实时场景测试
     */
    public static void restTr(){
        jedis.set("accountA", "100");
        jedis.set("accountB", "200");
        int count = 100;
        int accountA = Integer.parseInt(jedis.get("accountA"));
        if (accountA < count) {
            System.out.println("余额不足");
            return;
        } else {
            jedis.watch("accountA", "accountB");
            Transaction multi = jedis.multi();
            multi.decrBy("accountA", count);
            multi.incrBy("accountB", count);
            List<Object> exec = multi.exec();
            jedis.unwatch();
            if (exec.isEmpty()) {
                System.out.println("刷卡失败");
            } else {
                System.out.println("支付成功");
            }
        }
    }

 

posted @ 2019-03-17 21:08  zlAdmin  阅读(859)  评论(0)    收藏  举报