RedisTemplete 结合 @Transactional后Redis 的操作返回 null 的原因及解决方案
一、原因
RedisTemplete 开启了 Redis 事务支持后,在 @Transactional 中执行的 Redis 命令也会被认为是在 Redis 事务中执行的,要执行的递增命令会被放到队列中,不会立即返回执行后的结果,返回的是一个 null,需要等待事务提交时,队列中的命令才会顺序执行,最后 Redis 数据库的键值才会递增。
二、解决方案
-
弄两个 RedisTemplate Bean,一个是用来执行 Redis 事务的,一个是用来执行普通 Redis 命令的(不支持事务)。
@Configuration public class RedisTxConfig { private final RedisConnectionFactory redisConnectionFactory; public RedisTxConfig(RedisConnectionFactory redisConnectionFactory) { this.redisConnectionFactory = redisConnectionFactory; } @Bean(name = "stringRedisTemplate") public StringRedisTemplate stringRedisTemplate() { StringRedisTemplate template = new StringRedisTemplate(); template.setConnectionFactory(redisConnectionFactory); return template; } @Bean(name = "stringRedisTemplateForTx") public StringRedisTemplate stringRedisTemplateForTx() { StringRedisTemplate template = new StringRedisTemplate(); template.setEnableTransactionSupport(true); // 开启事务支持 template.setConnectionFactory(redisConnectionFactory); return template; } }
-
不同的地方引入不同的 Bean 就可以了
@Resource @Qualifier("stringRedisTemplate") private StringRedisTemplate stringRedisTemplate; @Resource @Qualifier("stringRedisTemplateForTx") private StringRedisTemplate stringRedisTemplateForTx;