redis方法加了@Transactional注解后方法内watch操作报错

springboot的redis方法增加了@Transactional事务注解后再用watch方法就会报错,请问怎么在Transactional事务标记的方法内监测要设置的键值有没有被改变呢
@Transactional标记的redis操作方法内如果不使用watch,即使当前要改变的key被别的线程改变了也会设置成功

参考GPT和自己的思路:

首先需要注意的是,Redis的watch命令和Spring的@Transactional注解所操作的事务是不同的事务机制,它们的作用域不同。

当一个方法被@Transactional注解标记后,该方法所有的Redis操作都将处于同一个事务中,因此在这个事务中,所有的Redis操作都将被作为一个整体进行提交或回滚。

而Redis的watch命令则是在一个事务外观察一个或多个键是否发生变化,如果该键在事务执行期间被其他客户端修改,则该事务将被回滚。

如果在@Transactional方法内使用watch命令,则需要确保这个key在事务执行期间没有被其他客户端修改,否则事务将被回滚。

在使用@Transactional注解的方法中,可以通过Spring提供的RedisTemplate的execute方法执行一个RedisCallback回调,进而操作Redis事务和watch命令。

具体代码实现如下:

@Component
public class RedisService {
    
    @Autowired
    private RedisTemplate redisTemplate;

    @Transactional
    public void redisTransactionalMethod() {
        redisTemplate.execute(new SessionCallback() {
            @Override
            public Object execute(RedisOperations operations) throws DataAccessException {
                // 执行watch命令
                operations.watch("key");

                // 获取key当前的值
                Object value = operations.opsForValue().get("key");

                // 在事务中执行Redis操作
                operations.multi();
                operations.opsForValue().set("key", "new value");
                operations.exec();

                return null;
            }
        });
    }
}

在上述代码中,我们可以看到,我们首先执行watch命令来观察key的变化,然后在一个事务中执行Redis操作。如果在事务执行期间,key被其他客户端修改,则该事务将被回滚。