Spring Redis删除不会删除键

21

我正在尝试删除Redis中的一个key,但不知何故它既没有被删除也没有抛出异常。以下是我的删除代码:

import com.example.service.CustomerService;
import com.example.model.Customer;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigInteger;
import java.util.*;

@Service
public class RedisCustomerService implements CustomerService {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate; 

    private String uniqueIdKey = "customerId";

    private BigInteger uniqueId() {
        long uniqueId = this.redisTemplate.opsForValue().increment(uniqueIdKey, 1);
        return BigInteger.valueOf(uniqueId);
    }

    private String lastNameKey(BigInteger id) {
        return "customer:ln:" + id;
    }

    private String firstNameKey(BigInteger id) {
        return "customer:fn:" + id;
    }

    @Override
    public void deleteCustomer(BigInteger id) {
        redisTemplate.opsForValue().getOperations().delete(String.valueOf(id));
    }
}

1
使用redis-cli中的monitor命令来查看发送到Redis服务器的命令。http://redis.io/commands/monitor - Didier Spezia
你的 Redis 是主实例吗?如果你尝试在从实例上删除一个键,就会出现这种情况。 - user1151446
6个回答

56

ValueOperations没有delete方法。因此以下代码将不起作用:

redisTemplate.opsForValue().delete(key);
尝试
redisTemplate.delete(key);

2

使用 ValueOperations 进行删除的一种替代技术是设置一个几乎立即过期的空值。Redis 将自行处理驱逐操作。

例如,您可以按以下方式设置一个值:

valueOperations.set("key", "value");

当您想要删除时,可以执行以下操作:
valueOperations.set("key", "", 1, TimeUnit.MILLISECONDS);

在这两个操作中,关键点必须相同。


2
如果你是超级尴尬的竞态条件的粉丝,这是一个非常有帮助的解决方案。 - Joey

2
在Spring Boot 2之前,如果在构建RestTemplate时没有指定序列化程序,则在Redis上会看到如下键:

"xac\xed\x00\x05t\x008mx.company.support.catalog.dao.keys"

。但是,在尝试使用redisTemplate.delete(key)删除它时,该键不会被删除。
一种简单的方法是以字节形式获取键并进行删除。以下是您类中的示例:
@Autowired
private RedisTemplate<String, Object> redisTemplate;

public boolean deleteKeyByPattern(String pattern) {
    Set<byte[]> patternResultConf = redisTemplate.getConnectionFactory().getConnection().keys(pattern.getBytes());
    if(Objects.nonNull(patternResultConf) && !patternResultConf.isEmpty()) {
        redisTemplate.getConnectionFactory().getConnection().del(patternResultConf.toArray(new byte[0][]));
    }
    return true;
}

0

试试这个:

public void deleteCustomer(BigInteger id) {
        redisTemplate.execute(new RedisCallback<String>() {
                @Override
                public String doInRedis(RedisConnection redisConnection) throws DataAccessException {
                        redisConnection.del(redisTemplate.getStringSerializer().serialize(String.valueOf(id)));
                        return null;
                }
        });
}

0
 public void deleteCustomer(BigInteger id) {
        redisTemplate.setDefaultSerializer(new StringRedisSerializer());
        redisTemplate.delete(String.valueOf(id));
 }

-2

没有可用的 getOperation:

@Override
public void deleteCustomer(BigInteger id) {
    redisTemplate.opsForValue().delete(String.valueOf(id));
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接