一:事故
在项目测试中,遇到一个事件创建失败问题,追踪日志发现分布式ID的获取值为空,导致后续表写入异常。
经排查锁定相关方法,具体方法经简化如下:
@Transactional
public String testRedisTrans(){
redisTemplate.setEnableTransactionSupport(true);
redisTemplate.multi();
redisTemplate.opsForValue().set("demo1","111111111");
redisTemplate.opsForValue().set("demo2","222222222");
redisTemplate.exec();
redisTemplate.setEnableTransactionSupport(false);
return redisTemplate.opsForValue().increment("countId",1).toString();
}
去除掉@Transactional注解后,发现问题解决
二:查找原因
根据源码分析,在执行exec方法的时候,当开启了 Redis 事务支持后,就会去绑定一个连接(bindConnection
),否则就去获取新的 Redis 连接(getConnection
)。这里我们是开启了的,所以再到 bindConnection
方法中查看如何绑定连接的。
接着往下看,关键代码如下所示,当开启了 Redis 事务支持,且添加了 @Transactional 注解时,就会执行 Redis 的 mutil 命令。
Redis Multi 命令 用于标记一个事务块的开始,事务块内的多条命令会按照先后顺序被放进一个队列当中,最后由 EXEC 命令原子性(atomic)地执行。
三:解决方案
在Redis配置类中,创建两个RedisTempLate对象,一个用来处理正常类,一个用来处理事务逻辑。
标签:Transactional,opsForValue,Redis,为空,ID,redisTemplate,分布式 From: https://www.cnblogs.com/daydayupHard/p/17479691.html