目录

前言

一、watch命令的作用

二、watch命令的执行过程

三、通过redis-cli体验watch命令

四、在springboot中使用watch监控


前言

通过redis事务及事务回滚机制这篇,记录了redis事务的大题使用方式,这篇记录一下redis的watch命令在事务中的应用,各位看到此博客的小伙伴,如有不对的地方请及时通过私信我或者评论此博客的方式指出,以免误人子弟。多谢!

一、watch命令的作用

到这里我知道,redis通过multi命令开启事务,通过exec命令提交事务,通过discard命令来取消事务中的命令,我们知道当一个线程去执行某些业务逻辑时,这些业务逻辑操作的数据也被其它线程共享了,会引发多线程中数据不一致的情况,通常我们会在操作共享数据时可以在代码层面和数据库层面加锁来解决这个问题,但是加锁通常对性能影响较大,参考了多线程中使用的 CAS去执行的,但是CAS会存在ABA的问题,ABA的问题可以使用乐观锁去避免,通常可以在数据库表中加一个version字段,每次更新时version加一,更新时如果version的old值和当前值不一致则不进行更新,其实redis也提供了保证数据一致性的watch命令,通过比较watch监控的键值对去保证数据的一致性。简单来说,watch命令的作用为:watch命令可以监控一个或多个键,当监控的键被修改(或删除),之后的事务就不会执行。监控一直持续到exec命令。之后通过命令演示加深印象。

二、watch命令的执行过程

在redis中使用watch命令可以决定事务是执行还是回滚。一般而言,可以在multi命令之前使用watch命令监控某些键值对,然后使用multi命令开启事务,执行各类对数据结构进行操作的命令,这个时候这些命令就会进入队列。当redis使用exec命令执行事务的时候,它首先会去比对被watch命令所监控的键值对,如果没有发生变化,那么它会执行事务队列中的命令,提交事务;如果发生变化,那么它不会执行任何事务中的命令,而去事务回滚。无论事务是否回滚,redis都会去取消执行事务前的watch命令。网上找的一个图(如下)说明了watch命令的使用方式。

三、通过redis-cli体验watch命令

先试一下成功提交的事务流程:

如上,在执行exec命令提交事务时,redis会在这个时间点检测key1的值在watch命令执行之后有没有被其它命令修改过,如果没有,则提交事务去执行。

再试一下watch的键在exec提交事务前被其它命令修改过的情况:

如上,在添加key1并使用watch监控并开启事务后,我们添加了key2并设置值为bbb,然后打开另一个窗口执行set key1 ccc命令对key1进行修改,然后切换窗口执行exec提交事务,因为key1被修改过,会返回nil,并且key2也是没有的,从而避免了产生ABA的问题。

四、在springboot中使用watch监控

在RedisService工具类中条件方法:

    /**
     * watch监控
     * @param keys
     * @return
     */
    public String watch(String... keys) {
        return jedis.watch(keys);
    }

添加测试方法:

    @Test
    public void watch() throws InterruptedException {
        redisService.flushDB();
        redisService.set("key1", "aaa");
        redisService.watch("key1");
        System.out.println("+++++++++++");
        Thread.sleep(5000);
        Transaction tr = redisService.multi();
        tr.set("key2", "bbb");
        tr.exec();
    }

测试时当看到控制台打印+++++时,,这里睡眠5秒就是为了方便测试效果,有时间去通过redis-cli修改下key1的值,如执行下set key1 ccc命令,执行测试方法后可以发现redis中只存了一个键key1,并且值为ccc,因为通过watch监控key1后改变了key1的值,所以在执行exec命令后,首先会去比对被watch命令所监控的键值对,发现key1的值发生了变化(由aaa变为ccc),那么它不会执行事务中的命令tr.set("key2","bbb"),而是去事务回滚,所以redis中没有key2这个键。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐