DATAREDIS-332 - @Transactional operation should use the same connection.
We only unbind the current redisConnectionFactory from the current thread if the transaction is not active anymore. Previously we performed the unbinding in RedisTemplate.execute(RedisCallback, boolean, boolean) overtime which lead to the fact that the next redis operation within the same transaction used a different redis connection, which could lead to exhaustion of the connection pool. We also ensure that we correctly unbind the RedisConnectionFactory resource from the TransactionSynchronizationManager on transaction completion in RedisTransactionSynchronizer.afterCompletion(int). Added test case supplied from issue. Original pull request: #134.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2014 the original author or authors.
|
||||
* Copyright 2011-2015 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.
|
||||
@@ -154,11 +154,12 @@ public abstract class RedisConnectionUtils {
|
||||
|
||||
if (!connHolder.isTransactionSyncronisationActive()) {
|
||||
connHolder.setTransactionSyncronisationActive(true);
|
||||
|
||||
|
||||
RedisConnection conn = connHolder.getConnection();
|
||||
conn.multi();
|
||||
|
||||
TransactionSynchronizationManager.registerSynchronization(new RedisTransactionSynchronizer(connHolder, conn));
|
||||
TransactionSynchronizationManager.registerSynchronization(new RedisTransactionSynchronizer(connHolder, conn,
|
||||
factory));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -252,26 +253,31 @@ public abstract class RedisConnectionUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* A {@link TransactionSynchronizationAdapter} that makes sure that the associated RedisConnection is released after the transaction completes.
|
||||
* A {@link TransactionSynchronizationAdapter} that makes sure that the associated RedisConnection is released after
|
||||
* the transaction completes.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
private static class RedisTransactionSynchronizer extends TransactionSynchronizationAdapter {
|
||||
|
||||
|
||||
private final RedisConnectionHolder connHolder;
|
||||
private final RedisConnection connection;
|
||||
private final RedisConnectionFactory factory;
|
||||
|
||||
/**
|
||||
* Creates a new {@link RedisTransactionSynchronizer}.
|
||||
*
|
||||
* @param connHolder
|
||||
* @param connection
|
||||
* @param factory
|
||||
*/
|
||||
private RedisTransactionSynchronizer(RedisConnectionHolder connHolder, RedisConnection connection) {
|
||||
|
||||
private RedisTransactionSynchronizer(RedisConnectionHolder connHolder, RedisConnection connection,
|
||||
RedisConnectionFactory factory) {
|
||||
|
||||
this.connHolder = connHolder;
|
||||
this.connection = connection;
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -294,9 +300,10 @@ public abstract class RedisConnectionUtils {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Closing bound connection after transaction completed with " + status);
|
||||
}
|
||||
|
||||
|
||||
connHolder.setTransactionSyncronisationActive(false);
|
||||
connection.close();
|
||||
TransactionSynchronizationManager.unbindResource(factory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2014 the original author or authors.
|
||||
* Copyright 2011-2015 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.
|
||||
@@ -199,9 +199,7 @@ public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperation
|
||||
return postProcessResult(result, connToUse, existingConnection);
|
||||
} finally {
|
||||
|
||||
if (enableTransactionSupport) {
|
||||
RedisConnectionUtils.unbindConnection(factory);
|
||||
} else {
|
||||
if (!enableTransactionSupport) {
|
||||
RedisConnectionUtils.releaseConnection(conn, factory);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user