在 Multi 中不能使用 Jedis。请改用 JedisTransaction

Cannot use Jedis when in Multi. Please use JedisTransaction instead

您好,我正在使用带有 spring 的 Redis 并使用 @Cacheable 实现它。 下面是我的 spring 和 redis 版本:

Redis: spring-data-redis 1.5.0.RELEASE 绝地武士 2.6.1

Spring: 4.1.1.RELEASE

下面是我的redis配置。

import java.util.Arrays;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import redis.clients.jedis.JedisPoolConfig;

@Configuration
@EnableCaching
public class CacheConfig extends CachingConfigurerSupport {

    private static final Logger log = Logger.getLogger(CacheConfig.class);

    @Autowired
    RedisConfig redisConfig;

    @Bean
    public JedisConnectionFactory redisConnectionFactory() {
        JedisConnectionFactory redisConnectionFactory = new JedisConnectionFactory();

        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxTotal(1000);
        config.setMaxIdle(10);
        config.setMinIdle(1);
        config.setMaxWaitMillis(30000);

        // Defaults
        redisConnectionFactory.setHostName(redisConfig.getRedisHost());
        redisConnectionFactory.setPort(redisConfig.getRedisPort());
        redisConnectionFactory.setDatabase(redisConfig.getRedisDatabase());
        redisConnectionFactory.setPoolConfig(config);
        redisConnectionFactory.setUsePool(true);

        return redisConnectionFactory;
    }

    @Bean
    public StringRedisSerializer redisSerializer() {
        StringRedisSerializer redisSerializer = new StringRedisSerializer();

        return redisSerializer;
    }

    @Bean
    public RedisTemplate<String, String> redisTemplate(JedisConnectionFactory cf, RedisSerializer sl) {
        RedisTemplate<String, String> redisTemplate = new RedisTemplate<String, String>();
        redisTemplate.setConnectionFactory(cf);
        redisTemplate.setKeySerializer(sl);
        redisTemplate.setHashKeySerializer(sl);
        redisTemplate.setEnableTransactionSupport(true);

        return redisTemplate;
    }

    @Bean
    public CacheManager cacheManager(RedisTemplate redisTemplate) {
        RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);

        // Number of seconds before expiration. Defaults to unlimited (0)
        cacheManager.setDefaultExpiration(3600);
        cacheManager.setCacheNames(Arrays.asList("my-cache"));
        cacheManager.setTransactionAware(true);
        cacheManager.setLoadRemoteCachesOnStartup(true);
        cacheManager.setUsePrefix(true);
        return cacheManager;
    }

}

但是我在 运行 代码上遇到以下异常:

org.springframework.dao.InvalidDataAccessApiUsageException: Cannot use Jedis when in Multi. Please use JedisTransaction instead.; nested exception is redis.clients.jedis.exceptions.JedisDataException: Cannot use Jedis when in Multi. Please use JedisTransaction instead.
    at org.springframework.data.redis.connection.jedis.JedisExceptionConverter.convert(JedisExceptionConverter.java:44)
    at org.springframework.data.redis.connection.jedis.JedisExceptionConverter.convert(JedisExceptionConverter.java:36)
    at org.springframework.data.redis.PassThroughExceptionTranslationStrategy.translate(PassThroughExceptionTranslationStrategy.java:37)
    at org.springframework.data.redis.FallbackExceptionTranslationStrategy.translate(FallbackExceptionTranslationStrategy.java:37)
    at org.springframework.data.redis.connection.jedis.JedisConnection.convertJedisAccessException(JedisConnection.java:196)
    at org.springframework.data.redis.connection.jedis.JedisConnection.close(JedisConnection.java:253)
    at org.springframework.data.redis.core.RedisConnectionUtils.unbindConnection(RedisConnectionUtils.java:230)
    at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:203)
    at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:153)
    at org.springframework.data.redis.cache.RedisCache.put(RedisCache.java:140)
    at org.springframework.data.redis.cache.RedisCache.put(RedisCache.java:125)
    at org.springframework.cache.transaction.TransactionAwareCacheDecorator.put(TransactionAwareCacheDecorator.java:85)
    at org.springframework.cache.interceptor.AbstractCacheInvoker.doPut(AbstractCacheInvoker.java:82)
    at org.springframework.cache.interceptor.CacheAspectSupport$CachePutRequest.apply(CacheAspectSupport.java:651)
    at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:358)
    at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:299)
    at org.springframework.cache.interceptor.CacheInterceptor.invoke(CacheInterceptor.java:61)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)

如果我做错了什么,请提出建议。

编辑:服务 Class 实施。

import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class LocationMasterService implements ILocationMasterService {
    private final Logger logger = Logger.getLogger(getClass());

    @Autowired
    ILocationMasterDao locationMasterDao;

    @Override
    @Cacheable(value = "my-cache", key = "#root.methodName")
    public List<LocationMasterResponse> getLocation() {
        logger.debug("Inside StoreMasterService createStore action ");
        List<LocationMasterResponse> locationList = null;

        List<LocationMasterEntity> locationMasterEntityList = null;
        locationMasterEntityList = locationMasterDao.getLocation();

        locationList = MapperUtil.map(locationMasterEntityList, LocationMasterResponse.class);


        return locationList;
    }

}

我遇到了同样的异常,在调试时发现问题是我正在缓存的值不可序列化并且在那里失败了。在我的案例中,异常和堆栈跟踪是错误的。检查您正在缓存的对象是否可序列化。