/* * JBoss, Home of Professional Open Source * Copyright 2006, Red Hat Middleware LLC, and individual contributors * as indicated by the @author tags. * See the copyright.txt in the distribution for a full listing * of individual contributors. * 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, v. 2.1. * This program is distributed in the hope that it will be useful, but WITHOUT A * 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, * v.2.1 along with this distribution; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. * * (C) 2005-2006, * @author JBoss Inc. */ /* * Copyright (C) 2000, * * Arjuna Solutions Limited, * Newcastle upon Tyne, * Tyne and Wear, * UK. * * $Id: TransactionCacheItem.java 2342 2006-03-30 13:06:17Z $ */ package com.arjuna.ats.internal.jts.recovery.transactions; import org.omg.CosTransactions.Status; import com.arjuna.ats.arjuna.common.Uid; import com.arjuna.ats.internal.jts.orbspecific.coordinator.ArjunaTransactionImple; import com.arjuna.ats.internal.jts.orbspecific.interposition.coordinator.ServerTransaction; import com.arjuna.ats.jts.logging.jtsLogger; /** * Would be an inner class of TransactionCache, except it is used by a static * method of TransactionCache. * (handles the creation of different kinds of transaction). * */ class TransactionCacheItem { private Uid _uid; private RecoveringTransaction _transaction; private String _type; private int _attempts; private Status _knownStatus; TransactionCacheItem(Uid uid,String type) { _uid = new Uid(uid); // copy as usual (I wonder ... ) _type = type; _attempts=0; // NoTransaction is used to mean that the status is not // actually known _knownStatus = Status.StatusNoTransaction; loadTransaction(true); } /** * activate the transaction. Allow for the possibility that the transaction * has been assumed complete since it was last heard of */ private boolean loadTransaction(boolean firstLoad) { if (_type.equals(ArjunaTransactionImple.typeName())) { _transaction = new RecoveredTransaction(_uid); if ( firstLoad && _transaction.getRecoveryStatus() == RecoveryStatus.ACTIVATE_FAILED) { // this is a previously unknown transaction, and its not in the store // perhaps it was previously assumed complete RecoveringTransaction assumed = new AssumedCompleteTransaction(_uid); if ( assumed.getRecoveryStatus() != RecoveryStatus.ACTIVATE_FAILED ) { if (jtsLogger.logger.isDebugEnabled()) { jtsLogger.logger.debug("Transaction "+_uid+" previously assumed complete"); } _transaction = assumed; _type = _transaction.type(); } } } else if (_type.equals(ServerTransaction.typeName() + "/JCA")) { try { _transaction = (RecoveringTransaction) Class.forName("com.arjuna.ats.internal.jta.recovery.jts.jca.coordinator.RecoveredServerTransaction").getConstructor(new Class[] {Uid.class, String.class}).newInstance(new Object[] {_uid, _type}); } catch (Exception e){ return false; } } else if (_type.equals(ServerTransaction.typeName())) { _transaction = new RecoveredServerTransaction(_uid); if ( firstLoad && _transaction.getRecoveryStatus() == RecoveryStatus.ACTIVATE_FAILED) { // this is a previously unknown transaction, and its not in the store // perhaps it was previously assumed complete RecoveringTransaction assumed = new AssumedCompleteServerTransaction(_uid); if ( assumed.getRecoveryStatus() != RecoveryStatus.ACTIVATE_FAILED ) { if (jtsLogger.logger.isDebugEnabled()) { jtsLogger.logger.debug("Transaction "+_uid+" previously assumed complete"); } _transaction = assumed; _type = _transaction.type(); } } } else if (_type.equals(AssumedCompleteTransaction.typeName())) { _transaction = new AssumedCompleteTransaction(_uid); } else if (_type.equals(AssumedCompleteServerTransaction.typeName())) { _transaction = new AssumedCompleteServerTransaction(_uid); } else { jtsLogger.i18NLogger.warn_recovery_transactions_TransactionCacheItem_2(_type); _transaction = null; return false; } return true; } /** * the transaction type has been changed */ void updateType() { _type = _transaction.type(); } /** * forget the activated copy of the transaction. Makes it subject to garbage collecting */ void clearTransaction() { _transaction = null; } RecoveringTransaction transaction() { return _transaction; } /** * Make sure the transaction is freshly activated and hasn't been replayed * assumed to be called from code synchronized on the TransactionCacheItem */ RecoveringTransaction freshTransaction() { if (_transaction == null || _transaction.getRecoveryStatus() == RecoveryStatus.REPLAYED) { /* * Not sure why we do a reload at all here. But if we do it * based on whether the transaction has really completed, things * stop working. Needs further investigation since there may * be a possible memory leak here. * * TO DO */ // if (!_transaction.allCompleted()) { // The transaction has been replayed, but they want a fresh one // Destroy this transaction and create a new // one thereby reactivating it. // Reactivate as the appropriate transaction class loadTransaction(false); } } return _transaction; } /** * keep (and return) a counter - used to record repeated failures */ int countAttempts() { return _attempts++; } /** * reset the attempt account */ void resetAttemptCount() { _attempts = 0; } /** * mutator for known status */ void setStatus(Status status) { _knownStatus = status; } /** * mutator for known status */ Status getStatus() { return _knownStatus; } }