diff --git a/pom.xml b/pom.xml index 2486f880c8..9196e50ba8 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-redis - 1.8.0.BUILD-SNAPSHOT + 1.8.0.DATAREDIS-548-SNAPSHOT Spring Data Redis diff --git a/src/main/java/org/springframework/data/redis/core/RedisConnectionUtils.java b/src/main/java/org/springframework/data/redis/core/RedisConnectionUtils.java index 7fcf5f0a8e..002aa1737c 100644 --- a/src/main/java/org/springframework/data/redis/core/RedisConnectionUtils.java +++ b/src/main/java/org/springframework/data/redis/core/RedisConnectionUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2011-2015 the original author or authors. + * Copyright 2011-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -39,6 +39,7 @@ * @author Costin Leau * @author Christoph Strobl * @author Thomas Darimont + * @author Mark Paluch */ public abstract class RedisConnectionUtils { @@ -199,8 +200,12 @@ public static void releaseConnection(RedisConnection conn, RedisConnectionFactor return; } - // Only release non-transactional/non-bound connections. - if (!isConnectionTransactional(conn, factory)) { + // release transactional/read-only and non-transactional/non-bound connections. + // transactional connections for read-only transactions get no synchronizer registered + if (isConnectionTransactional(conn, factory) + && TransactionSynchronizationManager.isCurrentTransactionReadOnly()) { + unbindConnection(factory); + } else if (!isConnectionTransactional(conn, factory)) { if (log.isDebugEnabled()) { log.debug("Closing Redis Connection"); } diff --git a/src/main/java/org/springframework/data/redis/core/RedisTemplate.java b/src/main/java/org/springframework/data/redis/core/RedisTemplate.java index 6ea8b595e3..b170cc5f78 100644 --- a/src/main/java/org/springframework/data/redis/core/RedisTemplate.java +++ b/src/main/java/org/springframework/data/redis/core/RedisTemplate.java @@ -74,6 +74,7 @@ * @author Christoph Strobl * @author Ninad Divadkar * @author Anqing Shao + * @author Mark Paluch * @param the Redis key type against which the template works (usually a String) * @param the Redis value type against which the template works * @see StringRedisTemplate @@ -212,10 +213,7 @@ public T execute(RedisCallback action, boolean exposeConnection, boolean // TODO: any other connection processing? return postProcessResult(result, connToUse, existingConnection); } finally { - - if (!enableTransactionSupport) { - RedisConnectionUtils.releaseConnection(conn, factory); - } + RedisConnectionUtils.releaseConnection(conn, factory); } } diff --git a/src/test/java/org/springframework/data/redis/connection/AbstractTransactionalTestBase.java b/src/test/java/org/springframework/data/redis/connection/AbstractTransactionalTestBase.java index 385c244e50..332f3489e3 100644 --- a/src/test/java/org/springframework/data/redis/connection/AbstractTransactionalTestBase.java +++ b/src/test/java/org/springframework/data/redis/connection/AbstractTransactionalTestBase.java @@ -39,6 +39,13 @@ import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.Transactional; +/** + * Base class with integration tests for transactional use. + * + * @author Thomas Darimont + * @author Christoph Strobl + * @author Mark Paluch + */ @RunWith(RelaxedJUnit4ClassRunner.class) @Transactional(transactionManager = "transactionManager") public abstract class AbstractTransactionalTestBase { @@ -129,6 +136,19 @@ public void valueOperationSetShouldBeCommittedCorrectly() { } } + /** + * @see DATAREDIS-548 + */ + @Test + @Transactional(readOnly = true) + public void valueOperationShouldWorkWithReadOnlyTransactions() { + + this.valuesShouldHaveBeenPersisted = false; + for (String key : KEYS) { + template.opsForValue().get(key); + } + } + /** * @see DATAREDIS-73 */ @@ -146,7 +166,7 @@ public void listOperationLPushShoudBeRolledBackCorrectly() { */ @Rollback(false) @Test - public void listOperationLPushShoudBeCommittedCorrectly() { + public void listOperationLPushShouldBeCommittedCorrectly() { this.valuesShouldHaveBeenPersisted = true; for (String key : KEYS) {