package com.easyooo.framework.support.transaction; import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.NamedThreadLocal; import org.springframework.util.Assert; /** * * 事务资源管理器 * * @see TransactionResource * * @author Killer */ public abstract class TransactionResourceManager { static final Logger logger = LoggerFactory.getLogger(TransactionResourceManager.class); private static final ThreadLocal<LinkedHashMap<Object, TransactionResource>> resources = new NamedThreadLocal<LinkedHashMap<Object, TransactionResource>>("transaction resources"); public static boolean isSynchronizationActive() { return (resources.get() != null); } public static void initSynchronization() { if (isSynchronizationActive()) { throw new IllegalStateException("Cannot activate Transaction resource - already active"); } if(logger.isDebugEnabled()){ logger.debug("Initializing Transaction resource."); } resources.set(new LinkedHashMap<Object, TransactionResource>()); } public static Map<Object, TransactionResource> getResourceMap() { if (!isSynchronizationActive()) { throw new IllegalStateException("The Transaction resource is not active"); } Map<Object, TransactionResource> map = resources.get(); return (Map<Object, TransactionResource>) Collections.unmodifiableMap(map); } public static boolean hasResource(Object key) { Object value = doGetResource(key); return (value != null); } @SuppressWarnings("unchecked") public static <T> T getResource(Object key) { return (T)doGetResource(key); } private static TransactionResource doGetResource(Object actualKey) { Map<Object, TransactionResource> map = resources.get(); if (map == null) { return null; } return map.get(actualKey); } public static void bindResource(Object key, TransactionResource value){ Assert.notNull(value, "Value must not be null"); LinkedHashMap<Object, TransactionResource> map = resources.get(); // set ThreadLocal Map if none found if (map == null) { throw new IllegalStateException("The Transaction resource is not active"); } map.put(key, value); if (logger.isDebugEnabled()) { logger.debug("Bound value [" + value + "] for key [" + key + "] to thread [" + Thread.currentThread().getName() + "]"); } } public static Object unbindResource(Object key){ Map<Object, TransactionResource> map = resources.get(); if (map == null) { throw new IllegalStateException("The Transaction resource is not active"); } Object value = map.remove(key); // Remove entire ThreadLocal if empty... if (map.isEmpty()) { resources.remove(); } if (value != null && logger.isTraceEnabled()) { logger.trace("Removed value [" + value + "] for key [" + key + "] from thread [" + Thread.currentThread().getName() + "]"); } return value; } public static void clear() { if (!isSynchronizationActive()) { throw new IllegalStateException("Cannot deactivate transaction resource - not active"); } resources.remove(); if (logger.isDebugEnabled()) { logger.debug("Thread["+ Thread.currentThread().getId() +"] transactional resource has been cleared."); } } }