Skip to content

Commit

Permalink
[jOOQ#5377] Refactored internals
Browse files Browse the repository at this point in the history
TLTransactionProvider and TLConnectionProvider are closely coupled. It is
better to move the CP into the TP as an inner class to stress this close
coupling.
  • Loading branch information
lukaseder committed Jul 4, 2016
1 parent d12aad0 commit 33d5632
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 110 deletions.
7 changes: 5 additions & 2 deletions jOOQ/src/main/java/org/jooq/impl/DefaultConfiguration.java
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
import org.jooq.conf.Settings;
import org.jooq.conf.SettingsTools;
import org.jooq.exception.ConfigurationException;
import org.jooq.impl.ThreadLocalTransactionProvider.ThreadLocalConnectionProvider;

/**
* A default implementation for configurations within a {@link DSLContext}, if no
Expand Down Expand Up @@ -715,6 +716,8 @@ public final Configuration set(DataSource newDataSource) {
@Override
public final Configuration set(ConnectionProvider newConnectionProvider) {
if (newConnectionProvider != null) {

// TODO Factor out this API in a more formal contract between TransactionProvider and ConnectionProvider
if (transactionProvider instanceof ThreadLocalTransactionProvider &&
!(newConnectionProvider instanceof ThreadLocalConnectionProvider))
throw new ConfigurationException("Cannot specify custom ConnectionProvider when Configuration contains a ThreadLocalTransactionProvider");
Expand Down Expand Up @@ -745,7 +748,7 @@ public final Configuration set(TransactionProvider newTransactionProvider) {
this.transactionProvider = newTransactionProvider;

if (newTransactionProvider instanceof ThreadLocalTransactionProvider)
this.connectionProvider = ((ThreadLocalTransactionProvider) newTransactionProvider).connection;
this.connectionProvider = ((ThreadLocalTransactionProvider) newTransactionProvider).localConnectionProvider;
}
else {
this.transactionProvider = new NoTransactionProvider();
Expand Down Expand Up @@ -945,7 +948,7 @@ public final ConnectionProvider connectionProvider() {
// local DefaultConnectionProvider, not the one from this configuration
TransactionProvider tp = transactionProvider();
ConnectionProvider transactional = tp instanceof ThreadLocalTransactionProvider
? ((ThreadLocalTransactionProvider) tp).connection
? ((ThreadLocalTransactionProvider) tp).localConnectionProvider
: (ConnectionProvider) data(DATA_DEFAULT_TRANSACTION_PROVIDER_CONNECTION);

return transactional == null ? connectionProvider : transactional;
Expand Down
14 changes: 7 additions & 7 deletions jOOQ/src/main/java/org/jooq/impl/DefaultTransactionProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -85,19 +85,19 @@ public class DefaultTransactionProvider implements TransactionProvider {
*/
private static final Savepoint IGNORED_SAVEPOINT = new DefaultSavepoint();

private final ConnectionProvider provider;
private final ConnectionProvider connectionProvider;
private final boolean nested;

public DefaultTransactionProvider(ConnectionProvider provider) {
this(provider, true);
public DefaultTransactionProvider(ConnectionProvider connectionProvider) {
this(connectionProvider, true);
}

/**
* @param nested Whether nested transactions via {@link Savepoint}s are
* supported.
*/
public DefaultTransactionProvider(ConnectionProvider provider, boolean nested) {
this.provider = provider;
public DefaultTransactionProvider(ConnectionProvider connectionProvider, boolean nested) {
this.connectionProvider = connectionProvider;
this.nested = nested;
}

Expand Down Expand Up @@ -136,7 +136,7 @@ private final DefaultConnectionProvider connection(Configuration configuration)
DefaultConnectionProvider connectionWrapper = (DefaultConnectionProvider) configuration.data(DATA_DEFAULT_TRANSACTION_PROVIDER_CONNECTION);

if (connectionWrapper == null) {
connectionWrapper = new DefaultConnectionProvider(provider.acquire());
connectionWrapper = new DefaultConnectionProvider(connectionProvider.acquire());
configuration.data(DATA_DEFAULT_TRANSACTION_PROVIDER_CONNECTION, connectionWrapper);
}

Expand Down Expand Up @@ -251,7 +251,7 @@ private final void brace(Configuration configuration, boolean start) {
// try-finally will ensure that the ConnectionProvider.release() call is made
finally {
if (!start) {
provider.release(connection.connection);
connectionProvider.release(connection.connection);
configuration.data().remove(DATA_DEFAULT_TRANSACTION_PROVIDER_CONNECTION);
}
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,10 @@
*/
public class ThreadLocalTransactionProvider implements TransactionProvider {

final DefaultTransactionProvider transaction;
final ThreadLocalConnectionProvider connection;
final ThreadLocal<Deque<Configuration>> configuration;
final DefaultTransactionProvider delegateTransactionProvider;
final ThreadLocalConnectionProvider localConnectionProvider;
final ThreadLocal<Connection> localTxConnection;
final ThreadLocal<Deque<Configuration>> localConfigurations;

public ThreadLocalTransactionProvider(ConnectionProvider provider) {
this(provider, true);
Expand All @@ -81,34 +82,35 @@ public ThreadLocalTransactionProvider(ConnectionProvider provider) {
* @param nested Whether nested transactions via {@link Savepoint}s are
* supported.
*/
public ThreadLocalTransactionProvider(ConnectionProvider provider, boolean nested) {
this.connection = new ThreadLocalConnectionProvider(provider);
this.transaction = new DefaultTransactionProvider(connection, nested);
this.configuration = new ThreadLocal<Deque<Configuration>>();
public ThreadLocalTransactionProvider(ConnectionProvider connectionProvider, boolean nested) {
this.localConnectionProvider = new ThreadLocalConnectionProvider(connectionProvider);
this.delegateTransactionProvider = new DefaultTransactionProvider(localConnectionProvider, nested);
this.localConfigurations = new ThreadLocal<Deque<Configuration>>();
this.localTxConnection = new ThreadLocal<Connection>();
}

@Override
public void begin(TransactionContext ctx) {
transaction.begin(ctx);
delegateTransactionProvider.begin(ctx);
configurations().push(ctx.configuration());
if (transaction.nestingLevel(ctx.configuration()) == 1)
connection.tl.set(((DefaultConnectionProvider) ctx.configuration().data(DATA_DEFAULT_TRANSACTION_PROVIDER_CONNECTION)).connection);
if (delegateTransactionProvider.nestingLevel(ctx.configuration()) == 1)
localTxConnection.set(((DefaultConnectionProvider) ctx.configuration().data(DATA_DEFAULT_TRANSACTION_PROVIDER_CONNECTION)).connection);
}

@Override
public void commit(TransactionContext ctx) {
if (transaction.nestingLevel(ctx.configuration()) == 1)
connection.tl.remove();
if (delegateTransactionProvider.nestingLevel(ctx.configuration()) == 1)
localTxConnection.remove();
configurations().pop();
transaction.commit(ctx);
delegateTransactionProvider.commit(ctx);
}

@Override
public void rollback(TransactionContext ctx) {
if (transaction.nestingLevel(ctx.configuration()) == 1)
connection.tl.remove();
if (delegateTransactionProvider.nestingLevel(ctx.configuration()) == 1)
localTxConnection.remove();
configurations().pop();
transaction.rollback(ctx);
delegateTransactionProvider.rollback(ctx);
}

Configuration configuration(Configuration fallback) {
Expand All @@ -117,13 +119,43 @@ Configuration configuration(Configuration fallback) {
}

private Deque<Configuration> configurations() {
Deque<Configuration> result = configuration.get();
Deque<Configuration> result = localConfigurations.get();

if (result == null) {
result = new ArrayDeque<Configuration>();
configuration.set(result);
localConfigurations.set(result);
}

return result;
}

final class ThreadLocalConnectionProvider implements ConnectionProvider {

final ConnectionProvider delegateConnectionProvider;

public ThreadLocalConnectionProvider(ConnectionProvider delegate) {
this.delegateConnectionProvider = delegate;
}

@Override
public final Connection acquire() {
Connection local = localTxConnection.get();

if (local == null)
return delegateConnectionProvider.acquire();
else
return local;
}

@Override
public final void release(Connection connection) {
Connection local = localTxConnection.get();

if (local == null)
delegateConnectionProvider.release(connection);
else if (local != connection)
throw new IllegalStateException(
"A different connection was released than the thread-bound one that was expected");
}
}
}

0 comments on commit 33d5632

Please sign in to comment.