Spring-data-redis问题
使用的RedisTemplate,做读写操作时候,都是要经过序列化和反序列化。最近遇到了一个问题,使用incr计数,存进去了一个数字(int类型),但是因为是序列化之后存进去的,调用incr方法时候报错了:
org.springframework.dao.InvalidDataAccessApiUsageException: ERR value is not an integer or out of range; nested exception is redis.clients.jedis.exceptions.JedisDataException: ERR value is not an integer or out of range
at org.springframework.data.redis.connection.jedis.JedisUtils.convertJedisAccessException(JedisUtils.java:72)
at org.springframework.data.redis.connection.jedis.JedisConnection.convertJedisAccessException(JedisConnection.java:135)
at org.springframework.data.redis.connection.jedis.JedisConnection.incrBy(JedisConnection.java:1099)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
...
RedisTemplate本身没有提供不需要序列化就可以存储的方法,有什么办法可以解决呢? --------------------编程问答-------------------- save方法,序列化是自己实现的:
public void save(final K redisKey,final V data){
if(redisKey != null && data != null){
redisTemplate.execute(new RedisCallback<V>() {
public V doInRedis(RedisConnection connection) throws DataAccessException {
byte[] bkey = ObjectTranscoder.serialize(redisKey);
connection.set(bkey,ObjectTranscoder.serialize(data));
connection.close();
return null;
}
});
}
}
incrBy方法:
public void incr(final K redisKey,final long increValue){
if(redisKey != null){
redisTemplate.execute(new RedisCallback<V>() {
public V doInRedis(RedisConnection connection) throws DataAccessException {
byte[] bkey = ObjectTranscoder.serialize(redisKey);
connection.incrBy(bkey, increValue);
connection.close();
return null;
}
});
}
} --------------------编程问答-------------------- 修改了一下,虽然功能是实现了,但是原子性没有了,并发时候会有问题,希望大神解决呀~
public void incr(final K redisKey,final long increValue){
if(redisKey != null){
redisTemplate.execute(new RedisCallback<V>() {
public V doInRedis(RedisConnection connection) throws DataAccessException {
byte[] bkey = ObjectTranscoder.serialize(redisKey);
Object obj = ObjectTranscoder.deserialize(connection.get(bkey));
if(obj == null){
connection.close();
return null;
}
long value = Long.valueOf(obj.toString()) + increValue;
long expitedTime = connection.ttl(bkey);
connection.setEx(bkey,expitedTime,ObjectTranscoder.serialize(value));
connection.close();
return null;
}
});
}
}
谢谢。 --------------------编程问答--------------------
JedisConnection con = this.jedisConnectionFactory.getConnection();
con.incr("a:a".getBytes());
这样试试看
补充:Java , Web 开发