Skip to content

Commit db0c921

Browse files
committed
TransactionSynchronizationManager eagerly cleans up void ResourceHolders on any access (SPR-8844, SPR-8845)
1 parent 641bc35 commit db0c921

File tree

1 file changed

+16
-3
lines changed

1 file changed

+16
-3
lines changed

org.springframework.transaction/src/main/java/org/springframework/transaction/support/TransactionSynchronizationManager.java

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2010 the original author or authors.
2+
* Copyright 2002-2011 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -154,6 +154,10 @@ private static Object doGetResource(Object actualKey) {
154154
// Transparently remove ResourceHolder that was marked as void...
155155
if (value instanceof ResourceHolder && ((ResourceHolder) value).isVoid()) {
156156
map.remove(actualKey);
157+
// Remove entire ThreadLocal if empty...
158+
if (map.isEmpty()) {
159+
resources.remove();
160+
}
157161
value = null;
158162
}
159163
return value;
@@ -175,8 +179,13 @@ public static void bindResource(Object key, Object value) throws IllegalStateExc
175179
map = new HashMap<Object, Object>();
176180
resources.set(map);
177181
}
178-
if (map.put(actualKey, value) != null) {
179-
throw new IllegalStateException("Already value [" + map.get(actualKey) + "] for key [" +
182+
Object oldValue = map.put(actualKey, value);
183+
// Transparently suppress a ResourceHolder that was marked as void...
184+
if (oldValue instanceof ResourceHolder && ((ResourceHolder) oldValue).isVoid()) {
185+
oldValue = null;
186+
}
187+
if (oldValue != null) {
188+
throw new IllegalStateException("Already value [" + oldValue + "] for key [" +
180189
actualKey + "] bound to thread [" + Thread.currentThread().getName() + "]");
181190
}
182191
if (logger.isTraceEnabled()) {
@@ -225,6 +234,10 @@ private static Object doUnbindResource(Object actualKey) {
225234
if (map.isEmpty()) {
226235
resources.remove();
227236
}
237+
// Transparently suppress a ResourceHolder that was marked as void...
238+
if (value instanceof ResourceHolder && ((ResourceHolder) value).isVoid()) {
239+
value = null;
240+
}
228241
if (value != null && logger.isTraceEnabled()) {
229242
logger.trace("Removed value [" + value + "] for key [" + actualKey + "] from thread [" +
230243
Thread.currentThread().getName() + "]");

0 commit comments

Comments
 (0)