redis默認是只支持簡單key的過期處理的,像SortedSet類型,也是針對整個set的過期處理,不支持對set的某個成員的過期處理;
為了解決這個問題,做法如下:
1.存儲key及值信息到redis,並將key存入set里,設置key的過期時間;
這樣key可以支持過期處理並在過期后移除key及值;但是set里的key還是存在的;
a、在需要判斷key過期的處理中,如 boolean containsKey(Object key) ,先在set集合拿到對應的key;
用ttl判斷可以是否存在,如不存在說明已過期,從set移除該key;
b、定時任務,有些情況,可以過期了后面也不會再用到,所以需要定時去清理key,checkExpire();
2.代碼如下
public boolean containsKey(Object key) {
final byte[] keyBytes = computeKey(key);
return (Boolean) template.execute(new RedisCallback<Boolean>() {
public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
waitForLock(connection);
Set<byte[]> keys =connection.zRange(setName,0,-1);
boolean isExist=false;
for (byte[] item : keys) {
if(Arrays.equals( keyBytes,item)){
Long remain= connection.ttl(item);
if(remain==-2){
connection.zRem(setName, item);//從set里移除;
}else {
isExist = true;
}
break;
}
}
return isExist;
}
}, true);
}
public void checkExpire() {
template.execute(new RedisCallback<Object>() {
public Object doInRedis(RedisConnection connection) throws DataAccessException {
waitForLock(connection);
//connection.multi();
Set<byte[]> keys =connection.zRange(setName,0,-1);
for (byte[] item : keys) {
Long remain= connection.ttl(item);
if(remain==-2){
//connection.del(item);
// remove key from set
connection.zRem(setName, item);
}
}
//connection.exec();
return null;
}
}, true);
}

