diff --git a/src/main/java/io/ebeaninternal/server/transaction/DefaultTransactionThreadLocal.java b/src/main/java/io/ebeaninternal/server/transaction/DefaultTransactionThreadLocal.java index 3502f0bc4..4bcd6b9ea 100644 --- a/src/main/java/io/ebeaninternal/server/transaction/DefaultTransactionThreadLocal.java +++ b/src/main/java/io/ebeaninternal/server/transaction/DefaultTransactionThreadLocal.java @@ -1,19 +1,17 @@ package io.ebeaninternal.server.transaction; import io.ebeaninternal.api.SpiTransaction; -import io.ebeaninternal.server.transaction.TransactionMap.State; + +import javax.persistence.PersistenceException; +import java.util.HashMap; +import java.util.Map; /** * Used to store Transactions in a ThreadLocal. */ public final class DefaultTransactionThreadLocal { - private static final ThreadLocal local = new ThreadLocal() { - @Override - protected synchronized TransactionMap initialValue() { - return new TransactionMap(); - } - }; + private static final ThreadLocal> local = ThreadLocal.withInitial(HashMap::new); /** * Not allowed. @@ -22,18 +20,24 @@ public final class DefaultTransactionThreadLocal { } /** - * Return the current TransactionState for a given serverName. This is for the - * local thread of course. + * Remove the transaction entry for the given serverName. */ - private static TransactionMap.State getState(String serverName) { - return local.get().getStateWithCreate(serverName); + private static void remove(String serverName) { + local.get().remove(serverName); } /** * Set a new Transaction for this serverName and Thread. */ public static void set(String serverName, SpiTransaction trans) { - getState(serverName).set(trans); + if (trans == null) { + remove(serverName); + } else { + SpiTransaction existingTransaction = local.get().put(serverName, trans); + if (existingTransaction != null && existingTransaction.isActive()) { + throw new PersistenceException("The existing transaction is still active?"); + } + } } /** @@ -46,50 +50,40 @@ public final class DefaultTransactionThreadLocal { *

*/ public static void replace(String serverName, SpiTransaction trans) { - getState(serverName).replace(trans); + if (trans == null) { + remove(serverName); + } else { + local.get().put(serverName, trans); + } } /** * Return the current Transaction for this serverName and Thread. */ public static SpiTransaction get(String serverName) { - TransactionMap map = local.get(); - State state = map.getState(serverName); - SpiTransaction t = (state == null) ? null : state.transaction; - if (map.isEmpty()) { - local.remove(); + return local.get().get(serverName); + } + + private static SpiTransaction obtain(String serverName) { + SpiTransaction transaction = local.get().remove(serverName); + if (transaction == null) { + throw new IllegalStateException("No current transaction for [" + serverName + "]"); } - return t; + return transaction; } /** * Commit the current transaction. */ public static void commit(String serverName) { - TransactionMap map = local.get(); - State state = map.removeState(serverName); - if (state == null) { - throw new IllegalStateException("No current transaction for [" + serverName + "]"); - } - state.commit(); - if (map.isEmpty()) { - local.remove(); - } + obtain(serverName).commit(); } /** * Rollback the current transaction. */ public static void rollback(String serverName) { - TransactionMap map = local.get(); - State state = map.removeState(serverName); - if (state == null) { - throw new IllegalStateException("No current transaction for [" + serverName + "]"); - } - state.rollback(); - if (map.isEmpty()) { - local.remove(); - } + obtain(serverName).rollback(); } /** @@ -112,14 +106,9 @@ public final class DefaultTransactionThreadLocal { * */ public static void end(String serverName) { - - TransactionMap map = local.get(); - State state = map.removeState(serverName); - if (state != null) { - state.end(); - } - if (map.isEmpty()) { - local.remove(); + SpiTransaction transaction = local.get().remove(serverName); + if (transaction != null) { + transaction.end(); } } diff --git a/src/main/java/io/ebeaninternal/server/transaction/TransactionMap.java b/src/main/java/io/ebeaninternal/server/transaction/TransactionMap.java deleted file mode 100644 index 033e6c74a..000000000 --- a/src/main/java/io/ebeaninternal/server/transaction/TransactionMap.java +++ /dev/null @@ -1,112 +0,0 @@ -package io.ebeaninternal.server.transaction; - -import io.ebeaninternal.api.SpiTransaction; - -import javax.persistence.PersistenceException; -import java.util.HashMap; -import java.util.Map; - - -/** - * Current transactions mapped by server name. - */ -public class TransactionMap { - - /** - * Map of State by serverName. - */ - private final Map map = new HashMap<>(); - - @Override - public String toString() { - return map.toString(); - } - - public boolean isEmpty() { - return map.isEmpty(); - } - - /** - * Return the State for a given serverName. - */ - public State getState(String serverName) { - - return map.get(serverName); - } - - /** - * Return the State for a given serverName. - */ - public State getStateWithCreate(String serverName) { - - return map.computeIfAbsent(serverName, k -> new State()); - } - - /** - * Remove and return the State for a given serverName. - */ - public State removeState(String serverName) { - return map.remove(serverName); - } - - /** - * The transaction and whether it is active. - */ - public static class State { - - SpiTransaction transaction; - - @Override - public String toString() { - return "txn[" + transaction + "]"; - } - - public SpiTransaction get() { - return transaction; - } - - /** - * Set the transaction. This will now be the current transaction. - */ - public void set(SpiTransaction trans) { - if (transaction != null && transaction.isActive()) { - throw new PersistenceException("The existing transaction is still active?"); - } - transaction = trans; - } - - /** - * Commit the transaction. - */ - public void commit() { - transaction.commit(); - transaction = null; - } - - /** - * Rollback the transaction. - */ - public void rollback() { - transaction.rollback(); - transaction = null; - } - - /** - * End the transaction. - */ - public void end() { - if (transaction != null) { - transaction.end(); - transaction = null; - } - } - - /** - * Used to replace transaction with a proxy. - */ - public void replace(SpiTransaction trans) { - transaction = trans; - } - - } -}