/* * Bitronix Transaction Manager * * Copyright (c) 2010, Bitronix Software. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU * Lesser General Public License, as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this distribution; if not, write to: * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ package bitronix.tm; import bitronix.tm.journal.DiskJournal; import bitronix.tm.journal.Journal; import bitronix.tm.journal.NullJournal; import bitronix.tm.recovery.Recoverer; import bitronix.tm.resource.ResourceLoader; import bitronix.tm.timer.TaskScheduler; import bitronix.tm.twopc.executor.*; import bitronix.tm.utils.InitializationException; import bitronix.tm.utils.ClassLoaderUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Container for all BTM services. * <p>The different services available are: {@link BitronixTransactionManager}, {@link Configuration}, {@link Journal}, * {@link TaskScheduler}, {@link ResourceLoader}, {@link Recoverer} and {@link Executor}. They are used in all places * of the TM so they must be globally reachable.</p> * * @author lorban */ public class TransactionManagerServices { private final static Logger log = LoggerFactory.getLogger(TransactionManagerServices.class); private static BitronixTransactionManager transactionManager; private static BitronixTransactionSynchronizationRegistry transactionSynchronizationRegistry; private static Configuration configuration; private static Journal journal; private static TaskScheduler taskScheduler; private static ResourceLoader resourceLoader; private static Recoverer recoverer; private static Executor executor; /** * Create an initialized transaction manager. * @return the transaction manager. */ public synchronized static BitronixTransactionManager getTransactionManager() { if (transactionManager == null) transactionManager = new BitronixTransactionManager(); return transactionManager; } /** * Create the JTA 1.1 TransactionSynchronizationRegistry. * @return the TransactionSynchronizationRegistry. */ public synchronized static BitronixTransactionSynchronizationRegistry getTransactionSynchronizationRegistry() { if (transactionSynchronizationRegistry == null) transactionSynchronizationRegistry = new BitronixTransactionSynchronizationRegistry(); return transactionSynchronizationRegistry; } /** * Create the configuration of all the components of the transaction manager. * @return the global configuration. */ public synchronized static Configuration getConfiguration() { if (configuration == null) configuration = new Configuration(); return configuration; } /** * Create the transactions journal. * @return the transactions journal. */ public synchronized static Journal getJournal() { if (journal == null) { String configuredJounal = getConfiguration().getJournal(); if ("disk".equals(configuredJounal)) journal = new DiskJournal(); else if ("null".equals(configuredJounal)) journal = new NullJournal(); else { try { Class clazz = ClassLoaderUtils.loadClass(configuredJounal); journal = (Journal) clazz.newInstance(); } catch (Exception ex) { throw new InitializationException("invalid journal implementation '" + configuredJounal + "'", ex); } } if (log.isDebugEnabled()) log.debug("using journal " + configuredJounal); } return journal; } /** * Create the task scheduler. * @return the task scheduler. */ public synchronized static TaskScheduler getTaskScheduler() { if (taskScheduler == null) { taskScheduler = new TaskScheduler(); taskScheduler.start(); } return taskScheduler; } /** * Create the resource loader. * @return the resource loader. */ public synchronized static ResourceLoader getResourceLoader() { if (resourceLoader == null) { resourceLoader = new ResourceLoader(); } return resourceLoader; } /** * Create the transaction recoverer. * @return the transaction recoverer. */ public synchronized static Recoverer getRecoverer() { if (recoverer == null) { recoverer = new Recoverer(); } return recoverer; } /** * Create the 2PC executor. * @return the 2PC executor. */ public synchronized static Executor getExecutor() { if (executor == null) { boolean async = getConfiguration().isAsynchronous2Pc(); if (async) { if (log.isDebugEnabled()) log.debug("trying to use ConcurrentExecutor"); executor = new ConcurrentExecutor(); if (!executor.isUsable()) { if (log.isDebugEnabled()) log.debug("trying to use BackportConcurrentExecutor"); executor = new BackportConcurrentExecutor(); } if (!executor.isUsable()) { if (log.isDebugEnabled()) log.debug("using SimpleAsyncExecutor"); executor = new SimpleAsyncExecutor(); } } else { if (log.isDebugEnabled()) log.debug("using SyncExecutor"); executor = new SyncExecutor(); } } return executor; } /** * Check if the transaction manager has started. * @return true if the transaction manager has started. */ public synchronized static boolean isTransactionManagerRunning() { return transactionManager != null; } /** * Check if the task scheduler has started. * @return true if the task scheduler has started. */ public synchronized static boolean isTaskSchedulerRunning() { return taskScheduler != null; } /** * Clear services references. Called at the end of the shutdown procedure. */ protected static synchronized void clear() { transactionManager = null; transactionSynchronizationRegistry = null; configuration = null; journal = null; taskScheduler = null; resourceLoader = null; recoverer = null; executor = null; } }