spring data redis防坑指南

本文探讨了Spring Data Redis中的两个潜在问题。第一个问题是每个操作都会获取新的连接,可能导致在高并发场景下连接争用。第二个问题是过度使用`execute`方法可能引发数据库连接死锁。建议优化连接管理和使用,以减少连接获取和释放次数,同时指出Spring Data Redis在对象序列化和反序列化上的便利性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

标题有点大。

spring很优秀,但也会有缺点。下面写两点spring data redis中的“准”坑


坑1:

每个封装操作都新取connection

比如

HashOperations<String, String, String> hashOps;

hashOps.values();

类似这样的封装,方法(比如上述values())内部都是使用execute方法

List<byte[]> rawValues = execute(new RedisCallback<List<byte[]>>() {


public List<byte[]> doInRedis(RedisConnection connection) {
return connection.hVals(rawKey);
}
}, true);

这个方法的特点是(具体可见org.springframework.data.redis.core.RedisTemplate 177行)先获取连接,然后执行回调(比如上述doInRedis()),最后释放连接。

如果业务复杂点,用redis频繁点,很容易会出现下述场景:

fun(){

hashOps.values();

hashOps.values();

hashOps.values();

}

即同一个方法中(或者更宽泛一点,整个servlet执行周期,可能不止一个fun)会有大量连接获取、释放的操作。这在线程很多的情况下会造成严重的连接争用,让你不得不“配合”线程数增加连接数,虽然redis服务端用nio让连接数问题不那么敏感,但用redis的时候一般都是为高性能场景,所以能“省”还是最好省点


坑2:

execute方法使用redis数据库连接死锁

这个坑有点“危言耸听”,其实不能完全怪spring data redis,但它却是起到了“诱导犯罪”的作用,其实和坑1有关联。

为了摆脱坑1中需要建立大量redis连接的缺点,其实我们也可以自己去调用execute方法,这样就可以实现下述模型了:

connection = connectionFactory.get(); // 隐藏在execute中,业务代码看不到

connection.ops();

connection.ops();

connection.ops();

connetion.release(); // 隐藏在execute中,业务代码看不到

这样就把原来需要n次获取、归还连接,变成只需1次获取、归还连接。但是,这个隐藏的“坑”就在你想要摆脱坑1时出现了。。。


假设你在

connection.ops();

connection.ops();

connection.ops();

总掺杂了坑1中提到的类似hashOps.values();操作,这时候数据库连接获取、释放就变成了

connectionFactory.get();  // 步骤A

connectionFactory.get();

业务操作();

connetion.release();

connetion.release();

老司机应该懂这个模型有啥问题


其实spring data redis的最常用封装对象jedis已足够简单,因为redis毕竟不是有复杂sql操作的数据库,它提供的基本都是原子api,而且spring data redis对新版本redis的新特性实现往往很滞后。。。远远不如官方客户端jedis那样及时。

但总要找个用的理由,好吧。1、spring data redis在对象序列化和反序列化上比较方便。2、spring data redis属于spring、属于spring data系列

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值