
利用Redis 事务 解决并发写问题
背景
三代项目中,为了优化预览发布的速度,精简app服务中的操作,所以app服务中只生成代码,然后调deploy服务整合、提交、构建部署。
由于代码又分成前端代码和后端代码,而且他们生成的时间是不一定的,所以方案就是不管是前端还是后端代码先生成,如果redis中没有一份代码,就证明是第一个请求过来的,将代码先存到redis中,后return,后面的请求将代码取出来,合并-> 整合-> 提交 -> 构建部署。于是就可能有这么一种情况,两个请求同时向redis存代码,导致后面的请求都走不了。
于是使用redis事务 来检测一个key的状态解决redis并发写问题
实现
redisTemplate.setEnableTransactionSupport(true);
// 监测一个key
redisTemplate.watch(key);
// 开启一条事务
redisTemplate.multi();
redisTemplate.opsForValue().set(key, integrateModel, 5, TimeUnit.MINUTES);
List<Object> result = redisTemplate.exec();
if (!CollectionUtils.isEmpty(result) && (boolean) result.get(0)) {
// 执行成功 此次请求结束
return;
}
// 执行失败 已经有请求存了一份 app or service 代码
// 继续往下走
流程分析:
redisTemplate.watch()
用于检测一个key的状态,查看这些key的内容是否被更改。
redisTemplate.multi()
用于开启一条事务
redisTemplate.exec()
提交事务,返回的数组,如果不为null 而且第一条是true 则执行成功,放在此代码体现在成功往redis中插入一条数据。
如果有另外一个请求在exec()
以前已经把watch
的key修改了,那么此条操作不会提交,并返回一个空数组,表示事务失败,体现在代码里就是只需要关注事务已经提交并且返回成功的状态,则当前请求结束。
后面的逻辑将从redis中取出事先存好的一份代码,然后合并到一起继续走下面的逻辑即可
浅谈redis事务
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 Henry's Lib
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果