SpringBoot整合redisTemplate时,多线程无法操作

1.我配置了一个redisTemplate

@Configuration
public class RedisConfig {

    /**
     * 生成操作Redis的bean--RedisTemplate,并将其注入到Spring容器中
     *
     * @param factory redis连接工厂
     * @return 配置好的RedisTemplate
     */
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        //为了自己开发方便,一般直接使用<String,Object>
        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
        template.setConnectionFactory(factory);
        //自定义序列化器
        Jackson2JsonRedisSerializer<Object> objectJackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
        //Json序列化配置使用ObjectMapper进行转义
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        objectJackson2JsonRedisSerializer.setObjectMapper(objectMapper);
        //String的序列化
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        //key采用String的序列化方式
        template.setKeySerializer(stringRedisSerializer);
        //hash的key也采用String的序列化方式
        template.setHashKeySerializer(stringRedisSerializer);
        //value序列化方式采用jackson
        template.setValueSerializer(stringRedisSerializer);
        //hash的value序列化方式采用jackson
        template.setHashValueSerializer(stringRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }
}

2.定义了一个Redis工具类注入到了Spring容器中

@Component
public class RedisUtil {
    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

    public String get(String from,String to,String key){
        ValueOperations<String, Object> ops = redisTemplate.opsForValue();
        try {
            return (String) ops.get(key + ":" + from + ":" + to);
        }
        catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    public void set(String from,String to,String key,String obj){
        ValueOperations<String, Object> ops = redisTemplate.opsForValue();
        try {
            redisTemplate.multi();
            ops.set(key + ":" + from + ":" + to,obj);
            redisTemplate.exec();
        }
        catch (Exception e){
            redisTemplate.discard();
        }
    }
}

3.开了一个线程来执行方法

@Component
@Slf4j
public class AsyncHandShakeTask {
    @Autowired
    private HandShakeService handShakeService;
    @Autowired
    private RedisUtil redisUtil;

    @Async
    public Future<String> doHandShake(String from,String to){
        long start = System.currentTimeMillis();
        log.info("***************开始加锁***************");
        redisUtil.set(from,to,"lock","1");
        log.info("***************开始执行握手***************");
        handShakeService.doHandShake();
        log.info("***************执行握手结束***************");
        log.info("***************开始解锁***************");
        redisUtil.set(from,to,"lock","0");
        long end = System.currentTimeMillis();
        log.info("*****任务全部完成,总耗时:" + (end - start) + "毫秒*****");
        return new AsyncResult<>("任务全部完成,总耗时:" + (end - start) + "毫秒");
    }

    @Async
    public void testRedis(){
        System.out.println("开始设置");
        com.platform.security.util.RedisUtil.set("1","2","test","v");
        System.out.println("设置完成");
    }
}

然后开启线程执行该方法时,就是执行不了,也不是报错,就是执行到

 redisUtil.set(from,to,"lock","1");

这句之后,线程自动就退出了。该句也能执行成功。
然后我就十分奇怪,之后,在网上找相关资料时发现一个redisTemplate实例只能占有一个jedis链接。所以感觉可能是这个原因,然后就自己直接使用jedis创建一个连接进行了操作,发现可行。
如果有大佬遇到过同样的情况请告知一二。


版权声明:本文为EEEEEEcho原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。