resourcemanager.java
来自「OpenJMS是一个开源的Java Message Service API 1.」· Java 代码 · 共 1,362 行 · 第 1/4 页
JAVA
1,362 行
/** * Redistribution and use of this software and associated documentation * ("Software"), with or without modification, are permitted provided * that the following conditions are met: * * 1. Redistributions of source code must retain copyright * statements and notices. Redistributions must also contain a * copy of this document. * * 2. Redistributions in binary form must reproduce the * above copyright notice, this list of conditions and the * following disclaimer in the documentation and/or other * materials provided with the distribution. * * 3. The name "Exolab" must not be used to endorse or promote * products derived from this Software without prior written * permission of Exoffice Technologies. For written permission, * please contact info@exolab.org. * * 4. Products derived from this Software may not be called "Exolab" * nor may "Exolab" appear in their names without prior written * permission of Exoffice Technologies. Exolab is a registered * trademark of Exoffice Technologies. * * 5. Due credit should be given to the Exolab Project * (http://www.exolab.org/). * * THIS SOFTWARE IS PROVIDED BY EXOFFICE TECHNOLOGIES AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * EXOFFICE TECHNOLOGIES OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Copyright 2000-2004 (C) Exoffice Technologies Inc. All Rights Reserved. * * $Id: ResourceManager.java,v 1.3 2005/08/30 07:26:49 tanderson Exp $ */package org.exolab.jms.messagemgr;import java.io.File;import java.io.FilenameFilter;import java.util.Comparator;import java.util.HashMap;import java.util.Iterator;import java.util.LinkedList;import java.util.TreeSet;import java.util.Vector;import javax.jms.JMSException;import javax.transaction.xa.XAException;import javax.transaction.xa.XAResource;import javax.transaction.xa.Xid;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.exolab.jms.client.JmsDestination;import org.exolab.jms.common.uuid.UUID;import org.exolab.jms.message.MessageImpl;import org.exolab.jms.persistence.DatabaseService;import org.exolab.jms.persistence.PersistenceException;import org.exolab.jms.service.Service;import org.exolab.jms.tranlog.DataTransactionLogEntry;import org.exolab.jms.tranlog.ExternalXid;import org.exolab.jms.tranlog.StateTransactionLogEntry;import org.exolab.jms.tranlog.TransactionLog;import org.exolab.jms.tranlog.TransactionLogException;import org.exolab.jms.tranlog.TransactionState;/** * The resource manager provides XA support for the JMS Server. * <p/> * The resource manager is responsible for managing the various transaction * identifiers and managing the association between transaction ids and * connections. * <p/> * The resource manager will store the global XID's and their state in the * database for recovery purposes. * <p/> * Messages that arrive, and are associated with an XID are not processed * through the {@link MessageMgr}. Instead they are routed to this resource * managers where they are cached until the associated XID is committed or * rolled back. If the transaction is successfully committed, through the 2PC * protocol the messages will pass through the system. * <p/> * Similarly, messages that are sent to consumers, either synchronously or * asynchronously are also cached by the resource manager until the global * transaction completes. * <p/> * On startup the resource manager will read all incomplete transactions, which * are incompleted into memory. It will then process trnasactions that have * timed out. * <p/> * The transaction manager will call the {@link #recover} method and obtain a * list of incomplete transaction for the purpose of completing them where * possible. * * @author <a href="mailto:jima@intalio.com">Jim Alateras</a> * @version $Revision: 1.3 $ $Date: 2005/08/30 07:26:49 $ */public class ResourceManager extends Service { /** * The extension for all transaction log files */ public final static String RM_LOGFILE_EXTENSION = ".log"; /** * This is used to indicate the garbage collection has been disabled and * that the client will take responsibility for all aspects of log file * management. This is useful in situations where the client wants to * archive the transaction log files * <p/> * This is the default mode for GC. */ public static final int GC_DISABLED = 0; /** * Synchronous gabrage collection is used to remove processed log files when * the last trnasaction, in that log file, has been successfully processed. * This is more efficient means since the log files does not need to be * scanned asynchronously to determine whether all the transactions have * been processed. */ public static final int GC_SYNCHRONOUS = 1; /** * Asynchronous garbage collection is used to remove processed log files * asynchronous (i.e in a different thread context). This is rather * expensive since it must manually scan each log file and determine whether * all transactions, in that file, have been closed. If this is the case * then it will remove the log file. */ public static final int GC_ASYNCHRONOUS = 2; /** * The message manager. */ private final MessageManager _messages; /** * The destination manager. */ private final DestinationManager _destinations; /** * This is the maximum size, in bytes, of each transaction log file. The * value can be overriden by the user */ private int _logFileSize = 1000000; /** * Maintains a collection of transaction log files currently in use by this * resource manager */ private TreeSet _logs = new TreeSet(new TranLogFileComparator()); /** * Maintain a mapping between the TRID (transaction id and the log file it * is associated with. */ private HashMap _tridToLogCache = new HashMap(); /** * Maintain a list of open TRIDs for a particular {@link TransactionLog} */ private HashMap _logToTridCache = new HashMap(); /** * This attribute is used to synchronize the modifications to the _tridToLog * _logToTrid attributes */ private final Object _cacheLock = new Object(); /** * This maintains a cache of all open transactions and the corresponding * data. The key is the transaction identifier and the object is a * LinkedList transaction entries, which includes both state and data */ private HashMap _activeTransactions = new HashMap(); /** * The directory where the log files are stored. This can be set by the * client */ private String _logDirectory = "."; /** * This is the number of the last log file created by the ResourceManager */ private long _lastLogNumber = 0; /** * The expiry time for transaction associated with this resource manager. * This will either be configured or passed in with the transaction context * The value is specified in seconds. */ private int _txExpiryTime = 120; /** * This attribute caches the garbage collection mode for the resouce * managers. Valid values are specified by the GC_* constants. * <p/> * By default garbage collection is disabled. */ private int _gcMode = GC_SYNCHRONOUS; /** * This is the id associated with this resource...need to work out who or * what sets this. */ private String _rid = UUID.next(); /** * The name of the service */ private final static String RM_SERVICE_NAME = "XAResourceManager"; /** * The prefix used for all transaction log files, which are created and * managed by the {@link TransactionLog} */ private final static String RM_LOGFILE_PREFIX = "ojmsrm"; /** * The logger */ private static final Log _log = LogFactory.getLog(ResourceManager.class); /** * Construct a resource manager using the default directory for its log * files. * <p/> * If the directory does not exist or there is no permisssion to access it, * then throw a ResourceManagerException. * * @param messages the message manager * @param destinations the destination manager * @param database the database service * @throws ResourceManagerException */ public ResourceManager(MessageManager messages, DestinationManager destinations, DatabaseService database) throws ResourceManagerException { super(RM_SERVICE_NAME); _messages = messages; _destinations = destinations; /* final String dir = "./logs"; _logDirectory = dir; File file = new File(dir); if ((!file.exists()) || (!file.isDirectory())) { throw new ResourceManagerException(dir + " does not exist or is not a directory"); } // build the list of existing log files. buildLogFileList(); // recover te list of log files recover(); */ } /** * Check whether garbage collection has been disabled * * @return boolean - true if gc is disabled */ public boolean gcDisabled() { return (_gcMode == GC_DISABLED) ? true : false; } /** * Log this published message so that it can be passed through the system * when the associated global transaction commits. * * @param xid - the global transaction identity * @param message - the message published * @throws TransactionLogException - error adding the entry * @throws ResourceManagerException - error getting the trnasaction log * @throws JMSException - if there is an issue with prep'ing the * message */ public synchronized void logPublishedMessage(Xid xid, MessageImpl message) throws TransactionLogException, ResourceManagerException, JMSException { _messages.prepare(message); logTransactionData(new ExternalXid(xid), _rid, createPublishedMessageWrapper(message)); } /** * Log that this message handle was sent to the consumer within the * specified global transaction identity. The message will be acknowledged * when the global transaction commits. Alternatively, if the global * transaction is rolled back the message handle will be returned to the * destination * * @param xid the global transaction identity * @param id the consumer receiving this message * @param handle - the handle of the message received * @throws TransactionLogException - error adding the entry * @throws ResourceManagerException - error getting the transaction log */ public synchronized void logReceivedMessage(Xid xid, long id, MessageHandle handle) throws TransactionLogException, ResourceManagerException { logTransactionData(new ExternalXid(xid), _rid, createReceivedMessageWrapper(id, handle)); } /** * Add an {@link StateTransactionLogEntry} using the specified txid, rid and * state * * @param xid - the transaction identifier * @param state - the transaction log state * @throws TransactionLogException - error adding the entry * @throws ResourceManagerException - error getting the trnasaction log */ public synchronized void logTransactionState(Xid xid, TransactionState state) throws TransactionLogException, ResourceManagerException { ExternalXid txid = new ExternalXid(xid); switch (state.getOrd()) { case TransactionState.OPENED_ORD: {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?