Redis不开启事务,不加@Transactional事务注解
@GetMapping(value = "/testRedis", produces = "application/json;charset=UTF-8")
public void testRedis() {
redisTemplate.opsForValue().set("count","1");
System.out.println(redisTemplate.opsForValue().increment("count", 1 ));
}
输出结果: 2
Redis不开启事务,加@Transactional事务注解
@GetMapping(value = "/testRedis", produces = "application/json;charset=UTF-8")
@Transactional
public void testRedis() {
redisTemplate.opsForValue().set("count","1");
System.out.println(redisTemplate.opsForValue().increment("count", 1 ));
}
输出结果: 2
Redis开启事务,不加@Transactional事务注解
@GetMapping(value = "/testRedis", produces = "application/json;charset=UTF-8")
public void testRedis() {
redisTemplate.setEnableTransactionSupport(true); //默认false
redisTemplate.opsForValue().set("count","1");
System.out.println(redisTemplate.opsForValue().increment("count", 1 ));
}
输出结果: 2 正常
开启Redis事务加@Transactional事务注解,在执行redis命令
开启 Redis 事务支持 + @Transactional 注解后,最后其实是标记了一个 Redis 事务块,后续的操作命令是
在这个事务块中执行的。
//一个进程内
@GetMapping(value = "/testRedis", produces = "application/json;charset=UTF-8")
@Transactional
public void testRedis() {
redisTemplate.setEnableTransactionSupport(true); //默认false
redisTemplate.multi();
redisTemplate.opsForValue().set("count","1");
System.out.println(redisTemplate.opsForValue().increment("count", 1 ));
redisTemplate.exec();
System.out.println(redisTemplate.opsForValue().increment("count", 1 ));
}
输出结果:null 3
//不同进程内
@GetMapping(value = "/testRedis", produces = "application/json;charset=UTF-8")
@Transactional
public void testRedis() {
redisTemplate.setEnableTransactionSupport(true); //默认false
redisTemplate.multi();
redisTemplate.opsForValue().set("count","1");
System.out.println(redisTemplate.opsForValue().increment("count", 1 ));
redisTemplate.exec();
}
@GetMapping(value = "/testRedis1", produces = "application/json;charset=UTF-8")
public void testRedis1() {
System.out.println(redisTemplate.opsForValue().increment("count", 1 ));
}
输出结果: 2 正常
@GetMapping(value = "/testRedis2", produces = "application/json;charset=UTF-8")
@Transactional
public void testRedis2() {
System.out.println(redisTemplate.opsForValue().increment("count", 1 ));
}
输出结果:null 实际值已经增加
结论
开启 Redis 事务支持 + @Transactional 注解后,最后其实是标记了一个 Redis 事务块,后续的操作命令是在这个事务块中执行的。 increment递增命令并不会返回递增后的结果,而是返回 null。 同一个进程内 不在一个redis事务内执行返回正常,不同进程内返回异常
异常解决方案如下:
方案一:每次 Redis 的事务操作完成后,关闭 Redis 事务支持,然后再执行 @Transactional 中的 Redis 命
令。
@GetMapping(value = "/testRedis", produces = "application/json;charset=UTF-8")
@Transactional
public void testRedis() {
redisTemplate.setEnableTransactionSupport(true); //默认false
redisTemplate.multi();
redisTemplate.opsForValue().set("count","1");
System.out.println(redisTemplate.opsForValue().increment("count", 1 ));
redisTemplate.exec();
redisTemplate.setEnableTransactionSupport(false);
}
方案二:创建两个 StringRedisTemplate,一个专门用来执行 Redis 事务,一个用来执行普通的 Redis 命令。