diff --git a/gradle.properties b/gradle.properties index ecbc97cf9..1201c0b95 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,7 +1,7 @@ slf4jVersion=1.7.12 junitVersion=4.12 jredisVersion=06052013 -jedisVersion=2.7.2 +jedisVersion=2.7.3 springVersion=4.1.6.RELEASE springDataBuildVersion=1.7.0.BUILD-SNAPSHOT log4jVersion=1.2.17 diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisConnection.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisConnection.java index 2fe78a467..48ea05327 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisConnection.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisConnection.java @@ -32,6 +32,7 @@ import java.util.concurrent.TimeUnit; import org.springframework.core.convert.converter.Converter; import org.springframework.dao.DataAccessException; +import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.redis.ExceptionTranslationStrategy; import org.springframework.data.redis.FallbackExceptionTranslationStrategy; import org.springframework.data.redis.RedisConnectionFailureException; @@ -55,6 +56,7 @@ import org.springframework.data.redis.core.ScanIteration; import org.springframework.data.redis.core.ScanOptions; import org.springframework.data.redis.core.types.RedisClientInfo; import org.springframework.util.Assert; +import org.springframework.util.ClassUtils; import org.springframework.util.ObjectUtils; import org.springframework.util.ReflectionUtils; import org.springframework.util.StringUtils; @@ -68,7 +70,6 @@ import redis.clients.jedis.Jedis; import redis.clients.jedis.Pipeline; import redis.clients.jedis.Protocol; import redis.clients.jedis.Protocol.Command; -import redis.clients.jedis.ProtocolCommand; import redis.clients.jedis.Queable; import redis.clients.jedis.Response; import redis.clients.jedis.ScanParams; @@ -102,18 +103,31 @@ public class JedisConnection extends AbstractRedisConnection { JedisConverters.exceptionConverter()); static { + CLIENT_FIELD = ReflectionUtils.findField(BinaryJedis.class, "client", Client.class); - ReflectionUtils.makeAccessible(CLIENT_FIELD); - SEND_COMMAND = ReflectionUtils.findMethod(Connection.class, "sendCommand", new Class[] { ProtocolCommand.class, - byte[][].class }); + ReflectionUtils.makeAccessible(CLIENT_FIELD); + + try { + Class commandType = ClassUtils.isPresent("redis.clients.jedis.ProtocolCommand", null) ? ClassUtils.forName( + "redis.clients.jedis.ProtocolCommand", null) : ClassUtils.forName("redis.clients.jedis.Protocol$Command", + null); + + SEND_COMMAND = ReflectionUtils.findMethod(Connection.class, "sendCommand", new Class[] { commandType, + byte[][].class }); + } catch (Exception e) { + throw new NoClassDefFoundError( + "Could not find required flavor of command required by 'redis.clients.jedis.Connection#sendCommand'."); + } + ReflectionUtils.makeAccessible(SEND_COMMAND); + GET_RESPONSE = ReflectionUtils.findMethod(Queable.class, "getResponse", Builder.class); ReflectionUtils.makeAccessible(GET_RESPONSE); } private final Jedis jedis; private final Client client; - private final Transaction transaction; + private Transaction transaction; private final Pool pool; /** flag indicating whether the connection needs to be dropped or not */ private boolean broken = false; @@ -168,7 +182,6 @@ public class JedisConnection extends AbstractRedisConnection { this.jedis = jedis; // extract underlying connection for batch operations client = (Client) ReflectionUtils.getField(CLIENT_FIELD, jedis); - transaction = new Transaction(client); this.pool = pool; @@ -727,6 +740,7 @@ public class JedisConnection extends AbstractRedisConnection { throw convertJedisAccessException(ex); } finally { txResults.clear(); + transaction = null; } } @@ -737,6 +751,10 @@ public class JedisConnection extends AbstractRedisConnection { new LinkedList>>(txResults), JedisConverters.exceptionConverter()))); return null; } + + if (transaction == null) { + throw new InvalidDataAccessApiUsageException("No ongoing transaction. Did you forget to call multi?"); + } List results = transaction.exec(); return convertPipelineAndTxResults ? new TransactionResultConverter>(txResults, JedisConverters.exceptionConverter()).convert(results) : results; @@ -744,6 +762,7 @@ public class JedisConnection extends AbstractRedisConnection { throw convertJedisAccessException(ex); } finally { txResults.clear(); + transaction = null; } } @@ -832,7 +851,7 @@ public class JedisConnection extends AbstractRedisConnection { pipeline.multi(); return; } - jedis.multi(); + this.transaction = jedis.multi(); } catch (Exception ex) { throw convertJedisAccessException(ex); }