Search in sources :

Example 56 with TransactionUID

use of com.sun.messaging.jmq.jmsserver.data.TransactionUID in project openmq by eclipse-ee4j.

the class TransactionHandler method doRemoteRollback.

private void doRemoteRollback(TransactionList translist, TransactionUID id, int nextState) throws BrokerException {
    if (nextState != TransactionState.ROLLEDBACK) {
        throw new BrokerException("Unexpected state " + nextState + " for transactionUID:" + id);
    }
    if (!translist.hasRemoteBroker(id)) {
        return;
    }
    if (Globals.getClusterBroadcast().getClusterVersion() < ClusterBroadcast.VERSION_410) {
        return;
    }
    TransactionBroker[] bas = null;
    try {
        bas = translist.getClusterTransactionBrokers(id);
        if (DEBUG_CLUSTER_TXN) {
            StringBuilder buf = new StringBuilder();
            buf.append("Rollback transaction ").append(id).append(", remote brokers");
            for (TransactionBroker ba : bas) {
                buf.append("\n\t").append(ba);
            }
            logger.log(logger.INFO, buf.toString());
        }
        BrokerAddress addr = null;
        UID tranpid = null;
        if (Globals.getDestinationList().isPartitionMode()) {
            tranpid = translist.getPartitionedStore().getPartitionID();
        }
        for (int i = 0; i < bas.length; i++) {
            if (Globals.getDestinationList().isPartitionMode()) {
                if (tranpid.equals(bas[i].getBrokerAddress().getStoreSessionUID())) {
                    continue;
                }
            } else if (bas[i].getBrokerAddress() == Globals.getMyAddress()) {
                continue;
            }
            addr = bas[i].getCurrentBrokerAddress();
            if (addr == Globals.getMyAddress()) {
                if (DEBUG_CLUSTER_TXN) {
                    logger.log(logger.INFO, "Transaction remote broker current address " + bas[i].toString() + " is my address, TUID=" + id);
                }
            } else {
                if (DEBUG_CLUSTER_TXN) {
                    logger.log(logger.INFO, "Transaction remote broker current address " + addr + ", TUID=" + id);
                }
            }
            try {
                if (addr != null) {
                    Globals.getClusterBroadcast().acknowledgeMessage2P(addr, (SysMessageID[]) null, (ConsumerUID[]) null, ClusterBroadcast.MSG_ROLLEDBACK, null, Long.valueOf(id.longValue()), tranpid, false, false);
                } else {
                    throw new BrokerDownException(br.getKString(br.X_CLUSTER_UNICAST_UNREACHABLE, bas[i]), Status.GONE);
                }
            } catch (BrokerException e) {
                String emsg = br.getKString(br.W_ROLLBACK_TXN_NOTIFY_REMOTE_BKR_FAIL, bas[i], id);
                if (e.getStatusCode() == Status.GONE || e.getStatusCode() == Status.TIMEOUT || e instanceof BrokerDownException) {
                    logger.log(logger.WARNING, emsg + ": " + e.getMessage());
                } else {
                    logger.logStack(logger.WARNING, emsg, e);
                }
            }
        }
    } catch (Exception e) {
        StringBuilder buf = new StringBuilder();
        if (bas != null) {
            for (TransactionBroker ba : bas) {
                buf.append("\n\t").append(ba);
            }
        }
        String emsg = br.getKString(br.W_ROLLBACK_TXN_NOTIFY_RMEOTE_BKRS_FAIL, buf.toString(), id);
        logger.logStack(logger.WARNING, emsg, e);
    }
}
Also used : ConsumerUID(com.sun.messaging.jmq.jmsserver.core.ConsumerUID) DestinationUID(com.sun.messaging.jmq.jmsserver.core.DestinationUID) UID(com.sun.messaging.jmq.util.UID) TransactionUID(com.sun.messaging.jmq.jmsserver.data.TransactionUID) BrokerException(com.sun.messaging.jmq.jmsserver.util.BrokerException) ConsumerUID(com.sun.messaging.jmq.jmsserver.core.ConsumerUID) TransactionBroker(com.sun.messaging.jmq.jmsserver.data.TransactionBroker) SysMessageID(com.sun.messaging.jmq.io.SysMessageID) BrokerAddress(com.sun.messaging.jmq.jmsserver.core.BrokerAddress) BrokerDownException(com.sun.messaging.jmq.jmsserver.util.BrokerDownException) SelectorFormatException(com.sun.messaging.jmq.util.selector.SelectorFormatException) IOException(java.io.IOException) AckEntryNotFoundException(com.sun.messaging.jmq.jmsserver.util.AckEntryNotFoundException) MaxConsecutiveRollbackException(com.sun.messaging.jmq.jmsserver.util.MaxConsecutiveRollbackException) BrokerException(com.sun.messaging.jmq.jmsserver.util.BrokerException) BrokerDownException(com.sun.messaging.jmq.jmsserver.util.BrokerDownException)

Example 57 with TransactionUID

use of com.sun.messaging.jmq.jmsserver.data.TransactionUID in project openmq by eclipse-ee4j.

the class TransactionHandler method convertPacketTid.

/**
 * Convert the transaction ID on an iMQ 2.0 packet to the new style.
 */
public static void convertPacketTid(IMQConnection con, Packet p) {
    long messagetid = p.getTransactionID();
    HashMap tidMap = (HashMap) con.getClientData(IMQConnection.TRANSACTION_IDMAP);
    if (tidMap == null) {
        // No transactions have been started yet. Can't convert ID
        return;
    }
    // Lookup old style ID in table
    TransactionUID id = (TransactionUID) tidMap.get(Long.valueOf(messagetid));
    if (id == null) {
        return;
    }
    // Convert the old ID to the corresponding new ID
    p.setTransactionID(id.longValue());
}
Also used : TransactionUID(com.sun.messaging.jmq.jmsserver.data.TransactionUID) HashMap(java.util.HashMap) CacheHashMap(com.sun.messaging.jmq.util.CacheHashMap)

Example 58 with TransactionUID

use of com.sun.messaging.jmq.jmsserver.data.TransactionUID in project openmq by eclipse-ee4j.

the class TransactionHandler method checkRefRequeued.

private boolean checkRefRequeued(TransactionList translist, TransactionUID id, PacketReference ref, SysMessageID sysid) throws BrokerException {
    HashMap addrmap = translist.retrieveAckBrokerAddresses(id);
    BrokerAddress oldAddr = (BrokerAddress) addrmap.get(sysid);
    if (ref == null && DL.isLocked(null, sysid)) {
        logger.log(logger.WARNING, "Message " + sysid + ((oldAddr == null) ? "" : " (" + oldAddr + ")") + " is in takeover, TUID=" + id);
        return true;
    }
    if (ref == null) {
        logger.log(logger.WARNING, Globals.getBrokerResources().getKString(BrokerResources.X_MESSAGE_REF_GONE, sysid) + " " + ((oldAddr == null) ? "" : " (" + oldAddr + ")") + ", TUID=" + id);
        return false;
    }
    if (ref.isOverrided()) {
        return true;
    }
    BrokerAddress currAddr = ref.getBrokerAddress();
    if (oldAddr == null && currAddr == null) {
        return false;
    }
    if ((oldAddr == null && currAddr != null) || (oldAddr != null && currAddr == null)) {
        return true;
    }
    if (!oldAddr.equals(currAddr)) {
        return true;
    }
    UID oldUID = oldAddr.getBrokerSessionUID();
    UID currUID = currAddr.getBrokerSessionUID();
    if (oldUID == null || currUID == null) {
        return false;
    }
    if (!oldUID.equals(currUID)) {
        return true;
    }
    return false;
}
Also used : ConsumerUID(com.sun.messaging.jmq.jmsserver.core.ConsumerUID) DestinationUID(com.sun.messaging.jmq.jmsserver.core.DestinationUID) UID(com.sun.messaging.jmq.util.UID) TransactionUID(com.sun.messaging.jmq.jmsserver.data.TransactionUID) HashMap(java.util.HashMap) CacheHashMap(com.sun.messaging.jmq.util.CacheHashMap) BrokerAddress(com.sun.messaging.jmq.jmsserver.core.BrokerAddress)

Example 59 with TransactionUID

use of com.sun.messaging.jmq.jmsserver.data.TransactionUID in project openmq by eclipse-ee4j.

the class ClusterTransactionManager method replayTransactionEvent.

@Override
void replayTransactionEvent(TransactionEvent txnEvent, HashSet dstLoadedSet) throws BrokerException, IOException {
    if (Store.getDEBUG()) {
        Globals.getLogger().log(Logger.DEBUG, getPrefix() + " replayTransactionEvent");
    }
    ClusterTransactionEvent clusterTxnEvent = (ClusterTransactionEvent) txnEvent;
    // replay to store on commit
    ClusterTransaction clusterTxn = clusterTxnEvent.clusterTransaction;
    int state = clusterTxn.getState();
    TransactionUID tid = clusterTxn.getTid();
    if (clusterTxnEvent.getSubType() == ClusterTransactionEvent.Type2PPrepareEvent) {
        // in prepared txn store and resetting the transaction log
        if (incompleteStored.containsKey(tid)) {
            if (Store.getDEBUG()) {
                String msg = getPrefix() + " found matching txn in prepared store on replay " + clusterTxn;
                Globals.getLogger().log(Logger.DEBUG, msg);
            }
        } else {
            addToIncompleteUnstored(clusterTxn);
        }
    } else if (clusterTxnEvent.getSubType() == ClusterTransactionEvent.Type2PCompleteEvent) {
        // we are completing a transaction
        // the transaction could be
        // a) unstored (prepare replayed earlier)
        // b) stored incomplete (prepare occurred before last checkpoint,
        // completion not written to prepared store yet)
        // This should therefore be the last entry in log.
        // c) stored complete (prepare occurred before last checkpoint,
        // and failure occurred after completion stored in prepared store
        BaseTransaction existingWork = null;
        if (incompleteUnstored.containsKey(tid)) {
            // a) unstored (prepare replayed earlier)
            if (state == TransactionState.ROLLEDBACK) {
                existingWork = removeFromIncompleteUnstored(tid);
            } else if (state == TransactionState.COMMITTED) {
                existingWork = incompleteUnstored.get(tid);
                existingWork.getTransactionDetails().setState(state);
                existingWork.getTransactionState().setState(state);
            }
        } else if (incompleteStored.containsKey(tid)) {
            // b) stored incomplete (prepare occurred before last checkpoint,
            // completion not written to prepared store yet)
            existingWork = removeFromIncompleteStored(tid);
            updateStoredState(tid, state);
            addToCompleteStored(existingWork);
        } else if (completeStored.containsKey(tid)) {
            // c) stored complete (prepare occurred before last checkpoint,
            // and failure occurred after completion stored in prepared store
            existingWork = completeStored.get(tid);
        }
        if (existingWork != null) {
            if (state == TransactionState.COMMITTED) {
                transactionLogManager.transactionLogReplayer.replayTransactionWork(existingWork.getTransactionWork(), tid, dstLoadedSet);
            }
        } else {
            logger.log(Logger.ERROR, "Could not find prepared work for completing two-phase transaction " + clusterTxn.getTid());
        }
    }
}
Also used : TransactionUID(com.sun.messaging.jmq.jmsserver.data.TransactionUID) BaseTransaction(com.sun.messaging.jmq.jmsserver.data.BaseTransaction) ClusterTransaction(com.sun.messaging.jmq.jmsserver.data.ClusterTransaction)

Example 60 with TransactionUID

use of com.sun.messaging.jmq.jmsserver.data.TransactionUID in project openmq by eclipse-ee4j.

the class FileStore method initTxnLogger.

// Initialize txn logging class
@Override
public boolean initTxnLogger() throws BrokerException {
    boolean storeNeedsRestart = false;
    if (removeStore || !Globals.txnLogEnabled()) {
        return storeNeedsRestart;
    }
    logger.log(logger.INFO, BrokerResources.I_TXNLOG_ENABLED);
    // create txn log writers
    String filename = null;
    try {
        SizeString filesize = config.getSizeProperty(TXNLOG_FILE_SIZE_PROP, DEFAULT_TXNLOG_FILE_SIZE);
        filename = MSG_LOG_FILENAME;
        msgLogWriter = new FileTransactionLogWriter(rootDir, filename, filesize.getBytes());
        msgLogWriter.setCheckPointListener(this);
        filename = ACK_LOG_FILENAME;
        ackLogWriter = new FileTransactionLogWriter(rootDir, filename, filesize.getBytes());
        ackLogWriter.setCheckPointListener(this);
        if (resetMessage || resetStore) {
            msgLogWriter.reset();
            ackLogWriter.reset();
            txnLoggerInited = true;
            return storeNeedsRestart;
        }
    } catch (IOException ex) {
        logger.logStack(Logger.ERROR, BrokerResources.E_CREATE_TXNLOG_FILE_FAILED, filename, ex);
        throw new BrokerException(br.getString(BrokerResources.E_CREATE_TXNLOG_FILE_FAILED, filename), ex);
    }
    // reconstruct persistence store if needed
    try {
        TransactionLogRecord rec;
        byte[] data;
        ByteArrayInputStream bis;
        DataInputStream dis;
        // Keep track of loaded dst
        HashSet dstLoadedSet = new HashSet();
        // Check to see if we need to process log files
        if (msgLogWriter.playBackRequired()) {
            storeNeedsRestart = true;
            logger.log(logger.FORCE, BrokerResources.I_PROCESS_MSG_TXNLOG);
            // All destinations need to be loaded
            Globals.getCoreLifecycle().initDestinations();
            Globals.getCoreLifecycle().initSubscriptions();
            int count = 0;
            Iterator itr = msgLogWriter.iterator();
            while (itr.hasNext()) {
                // Keep track the number of records processed
                count++;
                // Read in the messages
                rec = (TransactionLogRecord) itr.next();
                int recType = rec.getType();
                if (recType != TransactionLogType.PRODUCE_TRANSACTION) {
                    // Shouldn't happens
                    logger.log(logger.ERROR, BrokerResources.E_PROCESS_TXNLOG_RECORD_FAILED, String.valueOf(rec.getSequence()), "record type " + recType + " is invalid");
                    continue;
                }
                data = rec.getBody();
                bis = new ByteArrayInputStream(data);
                dis = new DataInputStream(bis);
                // Transaction ID
                long tid = dis.readLong();
                String tidStr = String.valueOf(tid);
                logger.log(logger.FORCE, BrokerResources.I_PROCESS_TXNLOG_RECORD, tidStr, String.valueOf(recType));
                // Process all msgs in the txn
                processTxnRecMsgPart(dis, dstLoadedSet);
                // Check to see if we need to commit the txn
                if (tid > 0) {
                    TransactionUID tuid = new TransactionUID(tid);
                    TransactionState state = tidList.getTransactionState(tuid);
                    if (state.getState() != TransactionState.NULL && state.getState() != TransactionState.COMMITTED) {
                        logger.log(logger.FORCE, BrokerResources.I_COMMIT_TXNLOG_RECORD, tidStr);
                        tidList.updateTransactionState(tuid, state, false);
                    }
                }
                dis.close();
                bis.close();
            }
            logger.log(logger.FORCE, BrokerResources.I_LOAD_MSG_TXNLOG, String.valueOf(count));
            logger.flush();
        }
        // of record, we'll just store it the same file for simplicity.
        if (ackLogWriter.playBackRequired()) {
            storeNeedsRestart = true;
            logger.log(logger.FORCE, BrokerResources.I_PROCESS_ACK_TXNLOG);
            // All destinations need to be loaded
            Globals.getCoreLifecycle().initDestinations();
            Globals.getCoreLifecycle().initSubscriptions();
            int count = 0;
            Iterator itr = ackLogWriter.iterator();
            while (itr.hasNext()) {
                // Keep track the number of records processed
                count++;
                // Read in the acks or msgs & acks
                rec = (TransactionLogRecord) itr.next();
                int recType = rec.getType();
                if (!(recType == TransactionLogType.CONSUME_TRANSACTION || recType == TransactionLogType.PRODUCE_AND_CONSUME_TRANSACTION)) {
                    // shouldn't happens
                    logger.log(logger.ERROR, BrokerResources.E_PROCESS_TXNLOG_RECORD_FAILED, String.valueOf(rec.getSequence()), "record type " + recType + " is invalid");
                    continue;
                }
                data = rec.getBody();
                bis = new ByteArrayInputStream(data);
                dis = new DataInputStream(bis);
                // Transaction ID
                long tid = dis.readLong();
                String tidStr = String.valueOf(tid);
                logger.log(logger.FORCE, BrokerResources.I_PROCESS_TXNLOG_RECORD, tidStr, String.valueOf(recType));
                if (recType == TransactionLogType.PRODUCE_AND_CONSUME_TRANSACTION) {
                    // Process all msgs in the txn first!
                    processTxnRecMsgPart(dis, dstLoadedSet);
                }
                // Process all acks in the txn
                processTxnRecAckPart(dis, dstLoadedSet);
                // Check to see if we need to commit the txn
                TransactionUID tuid = new TransactionUID(tid);
                TransactionState state = tidList.getTransactionState(tuid);
                if (state.getState() != TransactionState.NULL && state.getState() != TransactionState.COMMITTED) {
                    logger.log(logger.FORCE, BrokerResources.I_COMMIT_TXNLOG_RECORD, tidStr);
                    tidList.updateTransactionState(tuid, state, false);
                }
                dis.close();
                bis.close();
            }
            logger.log(logger.FORCE, BrokerResources.I_LOAD_ACK_TXNLOG, String.valueOf(count));
            logger.flush();
        }
        if (storeNeedsRestart) {
            // Now unload all the destinations that we've loaded so msgs can be routed correctly later on by the broker
            Iterator itr = dstLoadedSet.iterator();
            while (itr.hasNext()) {
                Destination d = (Destination) itr.next();
                // Sync changes to disk
                syncDestination(d);
                d.unload(true);
            }
            dstLoadedSet = null;
            // Sync changes to txn tables
            tidList.sync(null);
            tidList.syncTransactionAck(null);
            // Reset the txn log after the store is updated & synced
            msgLogWriter.reset();
            ackLogWriter.reset();
            logger.log(logger.FORCE, BrokerResources.I_RECONSTRUCT_STORE_DONE);
            logger.flush();
        }
    } catch (Throwable t) {
        logger.logStack(Logger.ERROR, BrokerResources.E_RECONSTRUCT_STORE_FAILED, t);
        throw new BrokerException(br.getString(BrokerResources.E_RECONSTRUCT_STORE_FAILED), t);
    }
    txnLoggerInited = true;
    return storeNeedsRestart;
}
Also used : TransactionState(com.sun.messaging.jmq.jmsserver.data.TransactionState) Destination(com.sun.messaging.jmq.jmsserver.core.Destination) BrokerException(com.sun.messaging.jmq.jmsserver.util.BrokerException) SizeString(com.sun.messaging.jmq.util.SizeString) IOException(java.io.IOException) DataInputStream(java.io.DataInputStream) TransactionUID(com.sun.messaging.jmq.jmsserver.data.TransactionUID) SizeString(com.sun.messaging.jmq.util.SizeString) ByteArrayInputStream(java.io.ByteArrayInputStream) TransactionLogRecord(com.sun.messaging.jmq.io.txnlog.TransactionLogRecord) Iterator(java.util.Iterator) FileTransactionLogWriter(com.sun.messaging.jmq.io.txnlog.file.FileTransactionLogWriter) HashSet(java.util.HashSet)

Aggregations

TransactionUID (com.sun.messaging.jmq.jmsserver.data.TransactionUID)71 TransactionList (com.sun.messaging.jmq.jmsserver.data.TransactionList)23 TransactionState (com.sun.messaging.jmq.jmsserver.data.TransactionState)22 BrokerException (com.sun.messaging.jmq.jmsserver.util.BrokerException)19 ConsumerUID (com.sun.messaging.jmq.jmsserver.core.ConsumerUID)18 SysMessageID (com.sun.messaging.jmq.io.SysMessageID)15 JMQXid (com.sun.messaging.jmq.util.JMQXid)13 IOException (java.io.IOException)13 HashMap (java.util.HashMap)12 TransactionBroker (com.sun.messaging.jmq.jmsserver.data.TransactionBroker)10 SelectorFormatException (com.sun.messaging.jmq.util.selector.SelectorFormatException)10 ArrayList (java.util.ArrayList)10 DestinationUID (com.sun.messaging.jmq.jmsserver.core.DestinationUID)8 Consumer (com.sun.messaging.jmq.jmsserver.core.Consumer)7 TransactionAcknowledgement (com.sun.messaging.jmq.jmsserver.data.TransactionAcknowledgement)7 ConnectionUID (com.sun.messaging.jmq.jmsserver.service.ConnectionUID)7 Iterator (java.util.Iterator)7 LinkedHashMap (java.util.LinkedHashMap)7 Map (java.util.Map)7 BrokerAddress (com.sun.messaging.jmq.jmsserver.core.BrokerAddress)6