在 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;
}
}
我遇到了同样的异常,在调试时发现问题是我正在缓存的值不可序列化并且在那里失败了。在我的案例中,异常和堆栈跟踪是错误的。检查您正在缓存的对象是否可序列化。
您好,我正在使用带有 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;
}
}
我遇到了同样的异常,在调试时发现问题是我正在缓存的值不可序列化并且在那里失败了。在我的案例中,异常和堆栈跟踪是错误的。检查您正在缓存的对象是否可序列化。