记一次redis操作在SessionCallback中开启事务operations.opsForValue().get(key)获取不到值的问题

BUG代码场景:

String key ="ceshi1";
        String newValue = "6";
        String oldValue = "7";
        //这里是能取到值的
        String s = redisOperator.get(key);
        System.out.println(s);

        SessionCallback<List<Object>> sessionCallback = new SessionCallback() {
            @Override
            public List<Object> execute(RedisOperations operations) throws DataAccessException {
                operations.multi();
                String redisValue = (String)operations.opsForValue().get(key);
                //这里没有获取到值。
                System.out.println(redisValue + "--"+ oldValue);
                if(Objects.equals(redisValue, oldValue) || Objects.isNull(redisValue)){
                    System.out.println( " in set");
                    operations.opsForValue().set(key, newValue);

                }
                return operations.exec();
            }
        };
        List<Object> execute = redisOperator.execute(sessionCallback);
        System.out.println(JsonUtil.toJson(execute));

追踪到源码时:因为开启了事务,所以 会进入如下所示,return null; 如果是没有开启事务,就会有值。
在这里插入图片描述
解决方案:
暂时没有想到 好的方式:等我想到了在来 补充!

补充,目前想到的是 通过自己写 lua脚本 去实现,lua脚本的方式 没有代码写起来那么方便。

### RedisTemplate `opsForValue()` 方法详解 `RedisTemplate.opsForValue()` 是 Spring Data Redis 提供的一个方法,用于获取针对 Redis 中字符串类型的键操作接口。返回的对象是一个实现了 `ValueOperations<K, V>` 接口的实例[^2]。 #### ValueOperations 的功能 `ValueOperations<K, V>` 主要提供了对 Redis 字符串类型数据的操作能力。以下是其常用的方法及其说明: 1. **设置单个键对** ```java operations.set(key, value); ``` 此方法会将指定的 key 设置为对应的 value [^1]。 2. **带过期时间的设置** ```java operations.set(key, value, timeout, TimeUnit.SECONDS); ``` 这种方式允许在存储的同时定义该键的有效期,单位可以是秒、毫秒等。 3. **批量设置多个键对** ```java Map<String, String> map = new HashMap<>(); map.put("key1", "value1"); map.put("key2", "value2"); operations.multiSet(map); ``` 可以一次性设置多组键对到 Redis 中。 4. **获取单个键的** ```java String result = operations.get(key); ``` 返回对应 key 存储的 value ,如果不存在则返回 null。 5. **增量操作** 对于数型的数据支持自增或自减: ```java Long incrementResult = operations.increment(key, delta); Long decrementResult = operations.decrement(key, delta); ``` 上述两个方法分别实现加法和减法运算,并更新原。 6. **追加字符串** 如果目标 key 已经存在,则会在原有基础上附加新的内容;否则创建新录。 ```java Integer appendLength = operations.append(key, additionalText); ``` 7. **删除特定字段** 删除某个已存在的 key 所关联的内容。 ```java Boolean deleteStatus = operations.getOperations().delete(key); ``` 8. **判断是否存在某 Key** 判断当前数据库里是否有这个 key 录。 ```java Boolean existsFlag = operations.getOperations().hasKey(key); ``` 9. **获取子字符串** 获取指定范围内的字符片段。 ```java String substring = operations.get(key, startOffset, endOffset); ``` 以上列举了一些常见的 API 调用形式,实际开发过程中可以根据业务需求灵活组合这些基础函数来完成复杂逻辑处理。 ### 使用场景分析 - 当应用程序需要缓存少量结构化信息时(比如用户的登录状态),可以通过 `ValueOperations` 将简单的对象序列化成 JSON 后保存至 Redis; - 实现计数器功能,利用原子性的增加/减少命令维护访问次数统计表; - 配合定时任务定期清理超时未使用的 session 数据等等[^3]。 ```java // 示例代码展示如何使用 ValueOperations 来管理用户在线状态 @Service public class UserService { @Autowired private RedisTemplate<String, Object> redisTemplate; public void login(String userId){ ValueOperations<String, Object> ops = redisTemplate.opsForValue(); ops.set(userId,"online",30,TimeUnit.MINUTES); // 用户上线并设定有效期为半小时 } public boolean isOnline(String userId){ ValueOperations<String, Object> ops = redisTemplate.opsForValue(); return ops.get(userId)!=null ? true:false; } } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值