From db0c921313a38ce26fa213a2292da5458f48ece6 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Mon, 28 Nov 2011 18:54:20 +0000 Subject: [PATCH] TransactionSynchronizationManager eagerly cleans up void ResourceHolders on any access (SPR-8844, SPR-8845) --- .../TransactionSynchronizationManager.java | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) 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 ff10f7fe0ef..876a561519e 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 @@ -1,5 +1,5 @@ /* - * Copyright 2002-2010 the original author or authors. + * Copyright 2002-2011 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,6 +154,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; @@ -175,8 +179,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()) { @@ -225,6 +234,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() + "]");