diff --git a/org.springframework.transaction/src/main/java/org/springframework/transaction/support/TransactionSynchronizationManager.java b/org.springframework.transaction/src/main/java/org/springframework/transaction/support/TransactionSynchronizationManager.java index f0d23dc9ba..93aafbdabd 100644 --- a/org.springframework.transaction/src/main/java/org/springframework/transaction/support/TransactionSynchronizationManager.java +++ b/org.springframework.transaction/src/main/java/org/springframework/transaction/support/TransactionSynchronizationManager.java @@ -155,6 +155,10 @@ public abstract class TransactionSynchronizationManager { // Transparently remove ResourceHolder that was marked as void... if (value instanceof ResourceHolder && ((ResourceHolder) value).isVoid()) { map.remove(actualKey); + // Remove entire ThreadLocal if empty... + if (map.isEmpty()) { + resources.remove(); + } value = null; } return value; @@ -176,8 +180,13 @@ public abstract class TransactionSynchronizationManager { map = new HashMap(); resources.set(map); } - if (map.put(actualKey, value) != null) { - throw new IllegalStateException("Already value [" + map.get(actualKey) + "] for key [" + + Object oldValue = map.put(actualKey, value); + // Transparently suppress a ResourceHolder that was marked as void... + if (oldValue instanceof ResourceHolder && ((ResourceHolder) oldValue).isVoid()) { + oldValue = null; + } + if (oldValue != null) { + throw new IllegalStateException("Already value [" + oldValue + "] for key [" + actualKey + "] bound to thread [" + Thread.currentThread().getName() + "]"); } if (logger.isTraceEnabled()) { @@ -226,6 +235,10 @@ public abstract class TransactionSynchronizationManager { if (map.isEmpty()) { resources.remove(); } + // Transparently suppress a ResourceHolder that was marked as void... + if (value instanceof ResourceHolder && ((ResourceHolder) value).isVoid()) { + value = null; + } if (value != null && logger.isTraceEnabled()) { logger.trace("Removed value [" + value + "] for key [" + actualKey + "] from thread [" + Thread.currentThread().getName() + "]");