Search in sources :

Example 11 with TransactionInfo

use of com.sun.messaging.jmq.jmsserver.persist.api.TransactionInfo in project openmq by eclipse-ee4j.

the class TransactionList method logTransactionInfo.

public static void logTransactionInfo(HashMap transactions, boolean autorollback, String logsuffix) {
    Logger logger = Globals.getLogger();
    BrokerResources br = Globals.getBrokerResources();
    /*
         * Loop through all transactions and count how many are in what state. This is done strictly for informational purposes.
         */
    // Number of transactions rolledback
    int nRolledBack = 0;
    // Number of prepared transactions
    int nPrepared = 0;
    // Number of committed transactions
    int nCommitted = 0;
    if (transactions != null && transactions.size() > 0) {
        Iterator itr = transactions.values().iterator();
        while (itr.hasNext()) {
            TransactionState _ts = ((TransactionInfo) itr.next()).getTransactionState();
            if (_ts.getState() == TransactionState.PREPARED) {
                nPrepared++;
                if (autorollback) {
                    nRolledBack++;
                }
            } else if (_ts.getState() != TransactionState.COMMITTED) {
                nRolledBack++;
            } else {
                nCommitted++;
            }
        }
        logger.log(Logger.INFO, br.getKString(br.I_NTRANS, Integer.valueOf(transactions.size()), Integer.valueOf(nRolledBack)) + logsuffix);
        Object[] args = { Integer.valueOf(transactions.size()), Integer.valueOf(nPrepared), Integer.valueOf(nCommitted) };
        logger.log(Logger.INFO, br.getKString(br.I_NPREPARED_TRANS, args) + logsuffix);
        if (nPrepared > 0) {
            if (autorollback) {
                logger.log(Logger.INFO, br.getKString(br.I_PREPARED_ROLLBACK) + logsuffix);
            } else {
                logger.log(Logger.INFO, br.getKString(br.I_PREPARED_NOROLLBACK) + logsuffix);
            }
        }
    }
}
Also used : Iterator(java.util.Iterator) TransactionInfo(com.sun.messaging.jmq.jmsserver.persist.api.TransactionInfo) Logger(com.sun.messaging.jmq.util.log.Logger) BrokerResources(com.sun.messaging.jmq.jmsserver.resources.BrokerResources)

Example 12 with TransactionInfo

use of com.sun.messaging.jmq.jmsserver.persist.api.TransactionInfo in project openmq by eclipse-ee4j.

the class TransactionList method loadTakeoverTxns.

// returns transaction acks
public Map loadTakeoverTxns(List txns, List remoteTxns, Map<String, String> msgs) throws BrokerException, IOException {
    logger.log(Logger.INFO, Globals.getBrokerResources().getKString(BrokerResources.I_PROCESSING_TAKEOVER_TRANS, Integer.valueOf(txns.size())));
    // hey process through the states
    Iterator itr = txns.iterator();
    Map acks = new HashMap();
    while (itr.hasNext()) {
        TransactionUID tid = (TransactionUID) itr.next();
        TransactionInfo ti = null;
        try {
            ti = pstore.getTransactionInfo(tid);
        } catch (Exception e) {
            String em = "Failed to get transaction " + tid + " information from store after takeover";
            logger.logStack(logger.ERROR, BrokerResources.E_INTERNAL_BROKER_ERROR, em, e);
            throw new BrokerException(em);
        }
        TransactionState ts = ti.getTransactionState();
        logger.log(Logger.DEBUG, "Processing transaction " + tid + ti.toString());
        try {
            if (ts.getState() != TransactionState.COMMITTED && ts.getState() != TransactionState.PREPARED) {
                pstore.removeTransactionAck(tid, false);
            }
            TransactionAcknowledgement[] ta = pstore.getTransactionAcks(tid);
            logger.log(Logger.DEBUG, "Processing transaction acks " + tid + " number=" + ta.length);
            List l = Arrays.asList(ta);
            acks.put(tid, l);
            addTransactionID(tid, ts, true, ti.getType(), false);
            if (ti.getType() == TransactionInfo.TXN_CLUSTER) {
                logClusterTransaction(tid, ts, ti.getTransactionBrokers(), true, false);
            }
            if (ts.getState() == TransactionState.PREPARED && ts.getOnephasePrepare()) {
                addDetachedTransactionID(tid);
            }
        } catch (Exception ex) {
            logger.logStack(Logger.ERROR, BrokerResources.E_INTERNAL_BROKER_ERROR, "error taking over " + tid, ex);
            acks.remove(tid);
        }
    }
    itr = remoteTxns.iterator();
    while (itr.hasNext()) {
        TransactionUID tid = (TransactionUID) itr.next();
        if (txns.contains(tid)) {
            continue;
        }
        TransactionInfo ti = null;
        try {
            ti = pstore.getTransactionInfo(tid);
        } catch (Exception e) {
            String em = "Failed to get remote transaction " + tid + " information from store after takeover";
            logger.logStack(logger.ERROR, BrokerResources.E_INTERNAL_BROKER_ERROR, em, e);
            throw new BrokerException(em);
        }
        TransactionState ts = ti.getTransactionState();
        if (DEBUG || DEBUG_CLUSTER_TXN) {
            logger.log(Logger.INFO, Globals.getBrokerResources().getString(BrokerResources.I_PROCESSING_REMOTE_TXN, tid + "[" + TransactionState.toString(ts.getState()) + "]" + ti.toString()));
        } else {
            logger.log(Logger.INFO, Globals.getBrokerResources().getString(BrokerResources.I_PROCESSING_REMOTE_TXN, tid + "[" + TransactionState.toString(ts.getState()) + "]"));
        }
        try {
            TransactionAcknowledgement[] ta = pstore.getTransactionAcks(tid);
            ArrayList l = new ArrayList();
            Iterator mitr = null;
            for (int i = 0; i < ta.length; i++) {
                mitr = msgs.keySet().iterator();
                while (mitr.hasNext()) {
                    String msgID = (String) mitr.next();
                    if (msgID.equals(ta[i].getSysMessageID().toString())) {
                        l.add(ta[i]);
                        if (DEBUG || DEBUG_CLUSTER_TXN) {
                            logger.log(Logger.INFO, "Processing remote transaction ack for TUID=" + tid + " " + ta[i].toString());
                        }
                    }
                }
            }
            if ((l.size() > 0)) {
                acks.put(tid, l);
                logger.log(Logger.INFO, "Processing remote transaction " + tid + "[" + TransactionState.toString(ts.getState()) + "] with acks " + l.size());
                if (ts.getState() != TransactionState.PREPARED && ts.getState() != TransactionState.COMMITTED) {
                    ts.setState(TransactionState.PREPARED);
                }
            }
            logRemoteTransaction(tid, ts, (TransactionAcknowledgement[]) l.toArray(new TransactionAcknowledgement[l.size()]), ti.getTransactionHomeBroker(), true, false, false);
            if (ts.getState() == TransactionState.COMMITTED) {
                txnReaper.addRemoteTransaction(tid, true);
            }
        } catch (Exception ex) {
            logger.logStack(Logger.ERROR, BrokerResources.E_INTERNAL_BROKER_ERROR, "error taking over " + tid, ex);
            acks.remove(tid);
        }
    }
    return acks;
}
Also used : BrokerException(com.sun.messaging.jmq.jmsserver.util.BrokerException) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) ArrayList(java.util.ArrayList) IOException(java.io.IOException) LoadException(com.sun.messaging.jmq.jmsserver.persist.api.LoadException) UnknownTransactionException(com.sun.messaging.jmq.jmsserver.util.UnknownTransactionException) BrokerException(com.sun.messaging.jmq.jmsserver.util.BrokerException) Iterator(java.util.Iterator) TransactionInfo(com.sun.messaging.jmq.jmsserver.persist.api.TransactionInfo) DestinationList(com.sun.messaging.jmq.jmsserver.core.DestinationList) ArrayList(java.util.ArrayList) List(java.util.List) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map)

Example 13 with TransactionInfo

use of com.sun.messaging.jmq.jmsserver.persist.api.TransactionInfo in project openmq by eclipse-ee4j.

the class TidList method storeRemoteTransaction.

/**
 * Store a remote transaction.
 *
 * @param id the id of the transaction to be persisted
 * @param ts the transaction's state to be persisted
 * @param acks the transaction's participant brokers
 * @param txnHomeBroker the transaction's home broker
 * @exception BrokerException if an error occurs while persisting or the same transaction id exists the store already
 * @exception NullPointerException if <code>id</code> is <code>null</code>
 */
public void storeRemoteTransaction(TransactionUID id, TransactionState ts, TransactionAcknowledgement[] acks, BrokerAddress txnHomeBroker, boolean sync) throws BrokerException {
    TransactionInfo txnInfo = null;
    boolean removedAcksFlag = false;
    try {
        if (tidMap.containsKey(id)) {
            logger.log(Logger.ERROR, BrokerResources.E_TRANSACTIONID_EXISTS_IN_STORE, id);
            throw new BrokerException(br.getString(BrokerResources.E_TRANSACTIONID_EXISTS_IN_STORE, id));
        }
        // We must store the acks first if provided
        if (acks != null && acks.length > 0) {
            txnAckList.storeAcks(id, acks, sync);
            removedAcksFlag = true;
        }
        // Now we store the txn;
        // TransactionState is mutable, so we must store a copy
        txnInfo = new TransactionInfo(new TransactionState(ts), txnHomeBroker, null, TransactionInfo.TXN_REMOTE);
        tidMap.put(id, txnInfo);
        if (sync) {
            sync(id);
        }
    } catch (RuntimeException e) {
        String msg = (txnInfo != null) ? id + " " + txnInfo : id.toString();
        logger.log(Logger.ERROR, BrokerResources.X_PERSIST_TRANSACTION_FAILED, msg, e);
        try {
            if (removedAcksFlag) {
                txnAckList.removeAcks(id, sync);
            }
        } catch (Exception ex) {
        // Just ignore because error has been logged at lower level
        }
        throw new BrokerException(br.getString(BrokerResources.X_PERSIST_TRANSACTION_FAILED, msg), e);
    }
}
Also used : TransactionState(com.sun.messaging.jmq.jmsserver.data.TransactionState) TransactionInfo(com.sun.messaging.jmq.jmsserver.persist.api.TransactionInfo) SizeString(com.sun.messaging.jmq.util.SizeString) LoadException(com.sun.messaging.jmq.jmsserver.persist.api.LoadException) PHashMapLoadException(com.sun.messaging.jmq.io.disk.PHashMapLoadException)

Example 14 with TransactionInfo

use of com.sun.messaging.jmq.jmsserver.persist.api.TransactionInfo in project openmq by eclipse-ee4j.

the class TidList method updateTransactionBrokerState.

/**
 * Update transaction's participant broker state if the txn's state matches the expected state.
 *
 * @param id the id of the transaction to be updated
 * @param expectedTxnState the expected transaction state
 * @param txnBkr the participant broker to be updated
 * @exception BrokerException if the transaction is not found in the store or the txn's state doesn't match the expected
 * state (Status.CONFLICT)
 */
void updateTransactionBrokerState(TransactionUID id, int expectedTxnState, TransactionBroker txnBkr, boolean sync) throws BrokerException {
    try {
        TransactionInfo txnInfo = (TransactionInfo) tidMap.get(id);
        if (txnInfo == null) {
            logger.log(Logger.ERROR, BrokerResources.E_TRANSACTIONID_NOT_FOUND_IN_STORE, id);
            throw new BrokerException(br.getString(BrokerResources.E_TRANSACTIONID_NOT_FOUND_IN_STORE, id), Status.NOT_FOUND);
        }
        TransactionState txnState = txnInfo.getTransactionState();
        if (txnState.getState() != expectedTxnState) {
            Object[] args = { txnBkr, id, TransactionState.toString(expectedTxnState), TransactionState.toString(txnState.getState()) };
            throw new BrokerException(br.getKString(BrokerResources.E_UPDATE_TXNBROKER_FAILED, args), Status.CONFLICT);
        }
        txnInfo.updateBrokerState(txnBkr);
        if (updateOptimization) {
            // To improve I/O performance, just persist the new
            // state as client data and not the whole record
            byte[] cd = generateClientData(id, txnInfo);
            PHashMapMMF tidMapMMF = (PHashMapMMF) tidMap;
            tidMapMMF.putClientData(id, cd);
        } else {
            tidMap.put(id, txnInfo);
        }
        if (sync) {
            sync(id);
        }
    } catch (Exception e) {
        logger.log(Logger.ERROR, BrokerResources.X_PERSIST_TRANSACTION_FAILED, id, e);
        throw new BrokerException(br.getString(BrokerResources.X_PERSIST_TRANSACTION_FAILED, id), e);
    }
}
Also used : TransactionState(com.sun.messaging.jmq.jmsserver.data.TransactionState) PHashMapMMF(com.sun.messaging.jmq.io.disk.PHashMapMMF) TransactionInfo(com.sun.messaging.jmq.jmsserver.persist.api.TransactionInfo) LoadException(com.sun.messaging.jmq.jmsserver.persist.api.LoadException) PHashMapLoadException(com.sun.messaging.jmq.io.disk.PHashMapLoadException)

Example 15 with TransactionInfo

use of com.sun.messaging.jmq.jmsserver.persist.api.TransactionInfo in project openmq by eclipse-ee4j.

the class TidList method clear.

/**
 * Clear all transactions that are NOT in the specified state.
 *
 * @param state State of transactions to spare
 */
void clear(int state, boolean sync) throws BrokerException {
    boolean error = false;
    Exception exception = null;
    Iterator itr = tidMap.entrySet().iterator();
    while (itr.hasNext()) {
        try {
            Map.Entry entry = (Map.Entry) itr.next();
            TransactionUID tid = (TransactionUID) entry.getKey();
            TransactionState ts = (TransactionState) entry.getValue();
            // Remove if not in prepared state
            if (ts.getState() != state) {
                // XXX PERF 12/7/2001 This operation updates disk
                // with every call.
                itr.remove();
                try {
                    txnAckList.removeAcks(tid, sync);
                } catch (BrokerException e) {
                    // TxnAckList Logs error
                    error = true;
                    exception = e;
                    break;
                }
            }
        } catch (RuntimeException e) {
            error = true;
            exception = e;
            logger.log(logger.ERROR, br.X_CLEAR_TXN_NOTIN_STATE_FAILED, Integer.valueOf(state), e);
        }
        if (sync) {
            sync(null);
        }
    }
    if (!error) {
        // We may have transactions left in the txnAckList that did not
        // have an entry in the tidMap (maybe it was removed by a commit
        // that never had a chance to complete processing the acks).
        // Check for those "orphaned" ack transactions here.
        TransactionUID[] tids = txnAckList.getAllTids();
        for (int i = 0; i < tids.length; i++) {
            TransactionInfo txnInfo = (TransactionInfo) tidMap.get(tids[i]);
            if (txnInfo == null || txnInfo.getTransactionStateValue() != state) {
                // Orphan. Remove from txnList
                try {
                    txnAckList.removeAcks(tids[i], sync);
                } catch (BrokerException e) {
                    // TxnAckList Logs error
                    error = true;
                    exception = e;
                    break;
                }
            }
        }
    }
    // If we got an error just clear all transactions.
    if (error) {
        clearAll(sync);
        throw new BrokerException(br.getString(br.X_CLEAR_TXN_NOTIN_STATE_FAILED, Integer.valueOf(state)), exception);
    }
}
Also used : TransactionState(com.sun.messaging.jmq.jmsserver.data.TransactionState) LoadException(com.sun.messaging.jmq.jmsserver.persist.api.LoadException) PHashMapLoadException(com.sun.messaging.jmq.io.disk.PHashMapLoadException) TransactionUID(com.sun.messaging.jmq.jmsserver.data.TransactionUID) TransactionInfo(com.sun.messaging.jmq.jmsserver.persist.api.TransactionInfo) PHashMap(com.sun.messaging.jmq.io.disk.PHashMap)

Aggregations

TransactionInfo (com.sun.messaging.jmq.jmsserver.persist.api.TransactionInfo)17 TransactionState (com.sun.messaging.jmq.jmsserver.data.TransactionState)8 LoadException (com.sun.messaging.jmq.jmsserver.persist.api.LoadException)6 PHashMapLoadException (com.sun.messaging.jmq.io.disk.PHashMapLoadException)5 PHashMap (com.sun.messaging.jmq.io.disk.PHashMap)4 TransactionBroker (com.sun.messaging.jmq.jmsserver.data.TransactionBroker)4 TransactionUID (com.sun.messaging.jmq.jmsserver.data.TransactionUID)4 IOException (java.io.IOException)4 SysMessageID (com.sun.messaging.jmq.io.SysMessageID)3 ConsumerUID (com.sun.messaging.jmq.jmsserver.core.ConsumerUID)3 Iterator (java.util.Iterator)3 JMSBridgeStore (com.sun.messaging.bridge.api.JMSBridgeStore)2 Packet (com.sun.messaging.jmq.io.Packet)2 PHashMapMMF (com.sun.messaging.jmq.io.disk.PHashMapMMF)2 Consumer (com.sun.messaging.jmq.jmsserver.core.Consumer)2 Destination (com.sun.messaging.jmq.jmsserver.core.Destination)2 DestinationUID (com.sun.messaging.jmq.jmsserver.core.DestinationUID)2 TransactionAcknowledgement (com.sun.messaging.jmq.jmsserver.data.TransactionAcknowledgement)2 ChangeRecordInfo (com.sun.messaging.jmq.jmsserver.persist.api.ChangeRecordInfo)2 HABrokerInfo (com.sun.messaging.jmq.jmsserver.persist.api.HABrokerInfo)2