org.redisson.client.RedisException: WRONGTYPE Operation against a key holding the wrong kind of value.

  • 分布式锁使用的key和别的键值对共用了同一个键

为什么这么说呢,写一段junit测试代码,这里RedissonClient配置就不展示了,有兴趣可以自行去了解一下

@RunWith(SpringRunner.class)
@SpringBootTest(classes = AccountServiceApplication.class)
class IScMemberProfitImplServiceTest {
	@Autowired
    private RedissonClient redissonClient;
	@Test
    void testRedisson() {
        //获取12345678对应的键
        RBucket<Object> bucket = redissonClient.getBucket("12345678");
        //获取键对应的值(此时为null)
        String o1 = (String)bucket.get();
        //设置同样的key
        RLock lock = redissonClient.getLock("12345678");
        //获取分布式锁,有效期2分钟
        lock.lock(2, TimeUnit.MINUTES);
        //测试重入锁
        //lock.lock(2, TimeUnit.MINUTES);
        //lock.lock(2, TimeUnit.MINUTES);
		//设置这个键对应的值为999,有效期为两分钟
        bucket.set("999",2, TimeUnit.MINUTES);
 		//释放分布式锁
        if(lock.isLocked()){
        	if(lock.isHeldByCurrentThread()){
            	lock.unlock();

运行完以上代码,线程在 if(lock.isHeldByCurrentThread()){ 处抛出如题异常,

回看以上代码,在分布式锁获取后,查看redis看到,redis中‘12345678’对应存的hash类型,内容如下
在这里插入图片描述
那运行到bucket.set("999",2, TimeUnit.MINUTES); 为什么不会报错呢? 分布式锁存储了hash类型,这不跟String类型冲突了吗

emmm,这要是在mysql确实执行不过去,但对于redis来说,set就意味着直接覆盖,因此,原来存储的不管是什么类型,都会直接覆盖

那为什么执行到if(lock.isHeldByCurrentThread()){ 这里又会报错呢?

额,接着上面所说,由于键 “12345678” 对应的值呗覆盖成了 “999” 字符串,线程执行到此行代码是,判断当前执行的线程是否与redis中存储的线程信息一致,但redis中的值结构已经不再是hash类型,因此会抛出异常

首先这个错误的说的是 对持有错误类型的key执行错误的操作 简单来说就key设置的值是字符串类型 你要用hash来访问就会报这种错误 解决方案如下: redis 127.0.0.1:6379>type key 此时会显示该key在所存储redis中的类型 比如: redis 127.0.0.1:6379>hash 则表示key为以hash类型存储在redis服务器里的,此时操作这个数据就必须使用hset、hget等操作方法。 使用错函数方法就会报上面的错误 (多半是因为这个原因)
操做redis时,想设置一个hash值,出现WRONGTYPE Operation against a key holding the wrong kind of value错误 HashOperations hashOperations = redisTemplate.opsForHash(); hashOperations.put("user", "name", "zhangsan"); Caused by: io.lettuce.core.RedisCommandExecutionExce
首先应该明白报这个错误说明了你用的jedis方法与redis服务器中存储数据的类型存在冲突。 例如:数据库中有一个key是usrInfo的数据存储的是Hash类型的,但是你使用jedis执行数据 操作的时候却使用了非Hash的操作方法,比如Sorted Sets里的方法。此时就会报 ERR Operation against a key holding the wrong kind of v
首先应该明白报这个错误说明了你用的jedis方法与redis服务器中存储数据的类型存在冲突。 例如:数据库中有一个key的数据存储的是Hash类型的,但是你使用jedis执行数据操作的时候却使用了非Hash的操作方法。此时就会报 WRONGTYPE Operation against a key holding the wrong kind of value这个错误! 问题解决: 先执行一条如下命令: redis 127.0.0.1:6379>type key 此时会显示出该key存.
redis报错:redis.clients.jedis.exceptions.JedisDataException: WRONGTYPE Operation against a key holding the wrong kind of value 错误原因:redis库中有相同key值但不同类型的数据。 解决办法: 删除数据库中的该key 转自:https://blog.csdn.net/stevejobson/article/details/78285436
RLock rLock = redissonClient.getLock("lockName");// 可以看做是获取一个连接 try { // 尝试加锁 愿意等待的时长 waitTime ; 加锁成功后自动释放锁的时长 leaseTime,大于0时不论加锁业务是否处理完毕都会释放锁 boolean locked = rLock.tryLock(1000, 2000, TimeUnit.MILLISECONDS);// 尝试加锁 if(lo...
在Spring Boot项目中使用Redisson实现分布式锁,需要按照以下步骤进行: 1. 在项目中引入Redisson依赖,可以在pom.xml文件中添加以下代码: <dependency> <groupId>org.redisson</groupId> <artifactId>redisson</artifactId> <version>3.13.3</version> </dependency> 2. 配置Redisson连接,可以在application.yml文件中添加以下代码: redisson: address: redis://127.0.0.1:6379 database: 0 connection-pool-size: 100 password: 123456 3. 创建RedissonClient对象,可以在Spring Boot项目的启动类中添加以下代码: @Configuration public class RedissonConfig { @Value("${redisson.address}") private String address; @Value("${redisson.password}") private String password; @Value("${redisson.connection-pool-size}") private int connectionPoolSize; @Value("${redisson.database}") private int database; @Bean public RedissonClient redissonClient() { Config config = new Config(); config.useSingleServer().setAddress(address) .setPassword(password) .setConnectionPoolSize(connectionPoolSize) .setDatabase(database); return Redisson.create(config); 4. 使用Redisson实现分布式锁,可以在需要加锁的代码中添加以下代码: @Autowired private RedissonClient redissonClient; public void lockMethod() { RLock lock = redissonClient.getLock("lockKey"); try { lock.lock(); // 被锁定的代码 } finally { lock.unlock(); 以上代码就是使用Redisson实现分布式锁的基本过程,实际项目中可能还需要根据实际情况进行修改和优化。