RedisTemplate实现Redis事务

这篇博客讨论了在多实例、多线程环境下如何利用Redis来统计执行成功和失败的次数,避免了MySQL在高频更新时可能出现的ABA问题。作者选择了Redis进行数据同步,并详细介绍了使用Redis事务确保数据一致性的方法,提供了一个名为CounterUtil的工具类示例,展示了如何在Java中实现这个功能。测试证明了这种方法的有效性。
摘要由CSDN通过智能技术生成

今天遇到需求要统计每次执行成功的个数和失败的个数,但是项目部署的是多实例的而且每个实例还是多线程的。
只使用多线程的计数器,没有很好的方法去实现多实例的数据汇总,想到使用redis或者mysql,由于是多线程的对统计字段变化频繁所以果断放弃mysql选择redis,
之前使用mysql遇到过多线程情况下数据出现ABA问题,所以在选择redis的时候不能只是单纯的更新数据,还要考虑多线程情况下数据的同步问题。

同时参考了:https://my.oschina.net/sxwailyc/blog/1973427

在此处记录一下,以后自己使用同时方便他人查看

public class CounterUtil {
    static {
        redisTemplate = ApplicationContextHolder.getBean("redisTemplate");
    }

    private static RedisTemplate redisTemplate;

   public static void counter(String key){

       List<Object> result =null;

       do{
           redisTemplate.setEnableTransactionSupport(true);//不可少
           int count = 0;
           redisTemplate.watch(key); //watch某个key,当该key被其它客户端改变时,则会中断当前的操作

           String value = (String) redisTemplate.opsForValue().get(key);
           if (!StringUtils.isEmpty(value)) {
               count = Integer.parseInt(value);
           }
           count = count + 1;

           redisTemplate.multi(); //开始事务
           redisTemplate.opsForValue().set(key, String.valueOf(count));

           try{
               result = redisTemplate.exec();//执行事务
           }catch(Exception e){
               //如果key被改变,提交事务时这里会报异常
           }
       }while(result == null || result.size()<=0);

   }
}

测试方法:使用多线程调用工具类,同时在自己的redis中查看对应key值的变化是否达到预期(我这里实在springboot项目的junit测试,其他测试方法可自己重写)

@Test
void contextLoads() {
        Runnable runable = new Runnable() {
            @Override
            public void run() {
            	String key = "test:success:count";
                CounterUtil.counter(key);
            }
        };

        List<Thread> threads = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            Thread thread = new Thread(runable, "thread-" + (i + 1));
            thread.start();
            threads.add(thread);
        }

        for (Thread thread : threads) {
            try {
                thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值