写点什么

Redis 事务详述,java 多并发面试题

用户头像
极客good
关注
发布于: 刚刚


注意禁止在 MULTI 和 EXEC 之间执行 WATCH 指令,这会导致 Redis 服务响应异常


2.6 UNWATCH

UNWATCH 用于取消 WATCH 命令对所有 key 的监视。如果在执行 WATCH 命令之后, EXEC 命令或 DISCARD 命令先被执行了的话,那么就不需要再执行 UNWATCH 了。因为 EXEC 命令会执行事务,因此 WATCH 命令的效果已经产生了;而 DISCARD 命令在取消事务的同时也会取消所有对 key 的监视,因此这两个命令执行之后,就没有必要执行 UNWATCH 了。



3、Jedis 使用事务




通过模拟一个简单的余额增加的例子,使用 Jedis 客户端来使用 Redis 的事务。


package?com.lizba.redis.tx;


import?redis.clients.jedis.Jedis;


import?redis.clients.jedis.Transaction;


import?java.math.BigDecimal;


import?java.util.List;


/**


*?<p>


*??????Redis 事务 demo


*?</p>



    *?@Author:?Liziba


    *?@Date:?2021/9/9?23:53


    */


    public?class?TransactionDemo?{


    private?Jedis?client;


    public?TransactionDemo(Jedis?client)?{


    this.client?=?client;


    }


    /**


    *?添加余额



      *?@param?userId????用户 id


      *?@param?amt???????添加余额


      *?@return


      */


      public?BigDecimal?addBalance(String?userId,?BigDecimal?amt)?{


      String?key?=?this.keyFormat(userId);


      //?初始用户余额为 0


      client.setnx(key,?"0");


      while?(true)?{


      client.watch(key);


      BigDecimal?balance?=?new?BigDecimal(client.get(key)).setScale(2,?BigDecimal.ROUND_HALF_UP);


      BigDecimal?amount?=?balance.add(amt);


      Transaction?tx?=?client.multi();


      tx.set(key,?amount.toPlainString());


      List<Object>?exec?=?tx.exec(


      【一线大厂Java面试题解析+核心总结学习笔记+最新架构讲解视频+实战项目源码讲义】
      浏览器打开:qq.cn.hn/FTf 免费领取
      复制代码


      );


      //?返回值不为空则证明 Redis 事务成功


      if?(exec?!=?null)?{


      break;


      }


      }


      return?new?BigDecimal(client.get(key)).setScale(2,?BigDecimal.ROUND_HALF_UP);


      }


      /**


      *?获取总金额



        *?@param?userId?用户 id


        *?@return


        */


        public?BigDecimal?getAmount(String?userId)?{


        String?amt?=?client.get(keyFormat(userId));


        return?new?BigDecimal(amt);


        }


        /**


        *?Redis?key


        *?@param?userId?用户 id


        *?@return


        */


        private?String?keyFormat(String?userId)?{


        return?String.format("balance:%s",userId);


        }


        }


        测试代码:


        package?com.lizba.redis.tx;


        import?redis.clients.jedis.Jedis;


        import?java.math.BigDecimal;


        import?java.util.concurrent.CountDownLatch;


        /**


        *?<p>


        *??????测试 Redis 事务


        *?</p>



          *?@Author:?Liziba


          *?@Date:?2021/9/10?0:03


          */


          public?class?TestTransactionDemo?{


          private?static?CountDownLatch?count?=?new?CountDownLatch(100);


          public?static?void?main(String[]?args)?throws?InterruptedException?{


          for?(int?i?=?0;?i?<?100;?i++)?{


          new?Thread(()?->?{


          Jedis?client?=?new?Jedis("192.168.211.109",?6379);


          TransactionDemo?demo?=?new?TransactionDemo(client);


          demo.addBalance("liziba",?BigDecimal.TEN);


          client.close();


          count.countDown();


          }).start();


          }


          count.await();


          Jedis?client?=?new?Jedis("192.168.211.109",?6379);


          BigDecimal?amt?=?new?TransactionDemo(client).getAmount("liziba");


          System.out.println(amt.toPlainString());


          }

          用户头像

          极客good

          关注

          还未添加个人签名 2021.03.18 加入

          还未添加个人简介

          评论

          发布
          暂无评论
          Redis事务详述,java多并发面试题