1 16 17 package org.springframework.transaction.support; 18 19 import java.util.ArrayList ; 20 import java.util.Collections ; 21 import java.util.Comparator ; 22 import java.util.HashMap ; 23 import java.util.LinkedList ; 24 import java.util.List ; 25 import java.util.Map ; 26 27 import org.apache.commons.logging.Log; 28 import org.apache.commons.logging.LogFactory; 29 30 import org.springframework.core.OrderComparator; 31 import org.springframework.util.Assert; 32 33 75 public abstract class TransactionSynchronizationManager { 76 77 private static final Log logger = LogFactory.getLog(TransactionSynchronizationManager.class); 78 79 80 private static final ThreadLocal resources = new ThreadLocal (); 81 82 private static final ThreadLocal synchronizations = new ThreadLocal (); 83 84 private static final Comparator synchronizationComparator = new OrderComparator(); 85 86 private static final ThreadLocal currentTransactionName = new ThreadLocal (); 87 88 private static final ThreadLocal currentTransactionReadOnly = new ThreadLocal (); 89 90 private static final ThreadLocal currentTransactionIsolationLevel= new ThreadLocal (); 91 92 private static final ThreadLocal actualTransactionActive = new ThreadLocal (); 93 94 95 99 108 public static Map getResourceMap() { 109 Map map = (Map ) resources.get(); 110 return (map != null ? Collections.unmodifiableMap(map) : Collections.EMPTY_MAP); 111 } 112 113 119 public static boolean hasResource(Object key) { 120 Assert.notNull(key, "Key must not be null"); 121 Map map = (Map ) resources.get(); 122 return (map != null && map.containsKey(key)); 123 } 124 125 132 public static Object getResource(Object key) { 133 Assert.notNull(key, "Key must not be null"); 134 Map map = (Map ) resources.get(); 135 if (map == null) { 136 return null; 137 } 138 Object value = map.get(key); 139 if (value != null && logger.isDebugEnabled()) { 140 logger.debug("Retrieved value [" + value + "] for key [" + key + "] bound to thread [" + 141 Thread.currentThread().getName() + "]"); 142 } 143 return value; 144 } 145 146 153 public static void bindResource(Object key, Object value) throws IllegalStateException { 154 Assert.notNull(key, "Key must not be null"); 155 Assert.notNull(value, "Value must not be null"); 156 Map map = (Map ) resources.get(); 157 if (map == null) { 159 map = new HashMap (); 160 resources.set(map); 161 } 162 if (map.containsKey(key)) { 163 throw new IllegalStateException ("Already value [" + map.get(key) + "] for key [" + key + 164 "] bound to thread [" + Thread.currentThread().getName() + "]"); 165 } 166 map.put(key, value); 167 if (logger.isDebugEnabled()) { 168 logger.debug("Bound value [" + value + "] for key [" + key + "] to thread [" + 169 Thread.currentThread().getName() + "]"); 170 } 171 } 172 173 180 public static Object unbindResource(Object key) throws IllegalStateException { 181 Assert.notNull(key, "Key must not be null"); 182 Map map = (Map ) resources.get(); 183 if (map == null || !map.containsKey(key)) { 184 throw new IllegalStateException ( 185 "No value for key [" + key + "] bound to thread [" + Thread.currentThread().getName() + "]"); 186 } 187 Object value = map.remove(key); 188 if (map.isEmpty()) { 190 resources.set(null); 191 } 192 if (logger.isDebugEnabled()) { 193 logger.debug("Removed value [" + value + "] for key [" + key + "] from thread [" + 194 Thread.currentThread().getName() + "]"); 195 } 196 return value; 197 } 198 199 200 204 209 public static boolean isSynchronizationActive() { 210 return (synchronizations.get() != null); 211 } 212 213 218 public static void initSynchronization() throws IllegalStateException { 219 if (isSynchronizationActive()) { 220 throw new IllegalStateException ("Cannot activate transaction synchronization - already active"); 221 } 222 logger.debug("Initializing transaction synchronization"); 223 synchronizations.set(new LinkedList ()); 224 } 225 226 236 public static void registerSynchronization(TransactionSynchronization synchronization) 237 throws IllegalStateException { 238 239 Assert.notNull(synchronization, "TransactionSynchronization must not be null"); 240 if (!isSynchronizationActive()) { 241 throw new IllegalStateException ("Transaction synchronization is not active"); 242 } 243 List synchs = (List ) synchronizations.get(); 244 synchs.add(synchronization); 245 } 246 247 254 public static List getSynchronizations() throws IllegalStateException { 255 if (!isSynchronizationActive()) { 256 throw new IllegalStateException ("Transaction synchronization is not active"); 257 } 258 List synchs = (List ) synchronizations.get(); 259 Collections.sort(synchs, synchronizationComparator); 261 return Collections.unmodifiableList(new ArrayList (synchs)); 265 } 266 267 272 public static void clearSynchronization() throws IllegalStateException { 273 if (!isSynchronizationActive()) { 274 throw new IllegalStateException ("Cannot deactivate transaction synchronization - not active"); 275 } 276 logger.debug("Clearing transaction synchronization"); 277 synchronizations.set(null); 278 } 279 280 281 285 291 public static void setCurrentTransactionName(String name) { 292 currentTransactionName.set(name); 293 } 294 295 301 public static String getCurrentTransactionName() { 302 return (String ) currentTransactionName.get(); 303 } 304 305 312 public static void setCurrentTransactionReadOnly(boolean readOnly) { 313 currentTransactionReadOnly.set(readOnly ? Boolean.TRUE : null); 314 } 315 316 331 public static boolean isCurrentTransactionReadOnly() { 332 return (currentTransactionReadOnly.get() != null); 333 } 334 335 351 public static void setCurrentTransactionIsolationLevel(Integer isolationLevel) { 352 currentTransactionIsolationLevel.set(isolationLevel); 353 } 354 355 372 public static Integer getCurrentTransactionIsolationLevel() { 373 return (Integer ) currentTransactionIsolationLevel.get(); 374 } 375 376 382 public static void setActualTransactionActive(boolean active) { 383 actualTransactionActive.set(active ? Boolean.TRUE : null); 384 } 385 386 397 public static boolean isActualTransactionActive() { 398 return (actualTransactionActive.get() != null); 399 } 400 401 402 411 public static void clear() { 412 clearSynchronization(); 413 setCurrentTransactionName(null); 414 setCurrentTransactionReadOnly(false); 415 setCurrentTransactionIsolationLevel(null); 416 setActualTransactionActive(false); 417 } 418 419 } 420 | Popular Tags |