场景:
使用redis缓存配置数据,采用hash结构缓存数据,考虑并发和一定的事务需求
环境
springboot 2.2.4,spring-data-redis 2.2.4,redis 5
两个注意点
使用redismanager查看存储的数据结构
现在要进行数据的插入操作,前提是param-param001的值不能改变,且保证隔离性(redis单线程)
针对hash的watch
如下图,这里要将key和hashKey作为watch参数,否则不会生效
operations.watch(Arrays.asList("param", "param001"));
operations.multi();
operations.exec的返回值获取
// 使用最普通的execute,返回结果就是sessioncallback的return结果
Object execute = redisTemplate.execute(new SessionCallback() {
@Override
public Object execute(RedisOperations operations) throws DataAccessException {
List exec;
do {
operations.watch(Arrays.asList("param", "param001"));
operations.multi();
// 在这一行断点,执行至此的时候,通过控制台改变param001对应的value值
operations.opsForHash().put("param", "param002", parameter);
exec = operations.exec();
System.out.println(exec);
operations.unwatch();
} while (exec.size() == 0);
return true;
}
});
而如果使用redisTemplate.executePipeLined,callback中的operations.exec是无法获取到返回值的,不论成功失败都返回常务为0的list也就无法满足事务回滚重试的需求,解决方法是,将redisTemplate.executePipeLined包在do while里,类似于redisTemplate.execute内部非do while
这两种重试的方法各有好处