Search in sources :

Example 36 with JMQXid

use of com.sun.messaging.jmq.util.JMQXid in project openmq by eclipse-ee4j.

the class XAResourceImpl method prepare.

/**
 * Ask the resource manager to prepare for a transaction commit of the transaction specified in xid.
 *
 * @param foreignXid A global transaction identifier.
 *
 * @exception XAException An error has occurred. Possible exception values are: XA_RB*, XAER_RMERR, XAER_RMFAIL,
 * XAER_NOTA, XAER_INVAL, or XAER_PROTO.
 *
 * @return A value indicating the resource manager's vote on the outcome of the transaction. The possible values are:
 * XA_RDONLY or XA_OK. If the resource manager wants to roll back the transaction, it should do so by raising an
 * appropriate XAException in the prepare method.
 */
private int prepare(Xid foreignXid, boolean onePhase, boolean insyncstate) throws XAException {
    if (_logger.isLoggable(Level.FINE)) {
        _logger.fine(_lgrPrefix + "XAResourceImpl (" + this.hashCode() + ") Prepare     " + printXid(foreignXid));
    }
    // JMS does not do RDONLY transactions - right?
    int result = XA_OK;
    // convert to jmq xid
    JMQXid jmqXid = new JMQXid(foreignXid);
    if (Debug.debug) {
        Debug.println("*=*=*=*=*=*=*=*=*=*=XAR:prepare:txid=\n" + jmqXid.toString());
    }
    try {
        // HACC
        if (this._session.isRollbackOnly) {
            Debug.println("*=*=*=*=*=*=*=*=*=*=XAR:prepare:forcing Rollback due to:" + this._session.rollbackCause.getMessage());
            // Debug.printStackTrace(this._session.rollbackCause);
            if (connectionConsumer != null && this._session.rollbackCause instanceof RemoteAcknowledgeException) {
                throw this._session.rollbackCause;
            }
            XAException xae = new XAException(XAException.XAER_RMFAIL);
            xae.initCause(this._session.rollbackCause);
            throw xae;
        }
        try {
            // Re-open if needed
            // _connection.openConnection(true);
            // Bug6664278 - must synced
            _connection.openConnectionFromRA(true);
        } catch (Exception oce) {
            // For now-retry once after a sec
            try {
                Thread.sleep(1000);
            } catch (Exception e) {
            }
            // _connection.openConnection(true);
            // Bug6664278 - must synced
            _connection.openConnectionFromRA(true);
        }
        if (_transaction == null) {
            // Debug.println("*=*=*=*=*=*=*=*=*=*=XAR:prepare:using 0 as txnID");
            _connection.getProtocolHandler().prepare(0L, jmqXid, onePhase);
        } else {
            // Debug.println("*=*=*=*=*=*=*=*=*=*=XAR:prepare:using real txnID");
            // Setup protocol Handler
            _transaction.setProtocolHandler(_connection.getProtocolHandler());
            // Perform XA prepare
            if (onePhase) {
                _connection.getProtocolHandler().prepare(0L, jmqXid, onePhase);
            } else {
                _transaction.prepareXATransaction(jmqXid);
            }
        }
        // _connection.closeConnection();
        // Bug6664278 - must synced
        _connection.closeConnectionFromRA();
    } catch (Throwable jmse) {
        // Debug.println("*=*=*=*=*=*=*=*=*=*=XAR:prepareXAException");
        Debug.printStackTrace(jmse);
        if (jmse instanceof XAException) {
            throw (XAException) jmse;
        }
        XAException xae = new XAException(XAException.XAER_RMFAIL);
        xae.initCause(jmse);
        if (jmse instanceof RemoteAcknowledgeException) {
            if (connectionConsumer != null) {
                ConnectionConsumerImpl cc = connectionConsumer;
                if (!cc.canRecreate()) {
                    throw xae;
                }
                try {
                    this.rollback(foreignXid);
                    xae = new XAException(XAException.XA_RBROLLBACK);
                    xae.initCause(jmse);
                    lastInternalRBCache.put(this, jmqXid);
                    lastInternalRB = true;
                } catch (Throwable t) {
                    SessionImpl.sessionLogger.log(Level.SEVERE, "Exception on rollback transaction " + jmqXid + " after prepared failed with remote exception", t);
                } finally {
                    cc.notifyRecreation((RemoteAcknowledgeException) jmse);
                }
            } else if (_session.isRemoteException((RemoteAcknowledgeException) jmse)) {
                try {
                    this.rollback(foreignXid);
                    xae = new XAException(XAException.XA_RBROLLBACK);
                    xae.initCause(jmse);
                    lastInternalRBCache.put(this, jmqXid);
                    lastInternalRB = true;
                } catch (Throwable t) {
                    SessionImpl.sessionLogger.log(Level.SEVERE, "Exception on rollback transaction " + jmqXid + " after prepare failed with remote exception", t);
                }
                if (!insyncstate) {
                    try {
                        _session.setInSyncState();
                    } catch (Throwable t) {
                        SessionImpl.sessionLogger.log(Level.SEVERE, "Exception on setting sync state after prepare " + jmqXid + " failed with remote exception", t);
                        throw xae;
                    }
                }
                try {
                    _session.recreateConsumers(true);
                } catch (Throwable t) {
                    SessionImpl.sessionLogger.log(Level.SEVERE, "Exception on recreating consumers after prepare " + jmqXid + " failed with remote exception", t);
                    throw xae;
                } finally {
                    if (!insyncstate) {
                        _session.releaseInSyncState();
                    }
                }
            }
        } else if (jmse instanceof TransactionPrepareStateFAILEDException) {
            if (onePhase) {
                if (_transaction == null || _session.isClosed || connectionConsumer != null) {
                    try {
                        _connection.getProtocolHandler().rollback(0L, jmqXid, connectionConsumer != null);
                        xae = new XAException(XAException.XA_RBROLLBACK);
                        xae.initCause(jmse);
                        lastInternalRBCache.put(this, jmqXid);
                        lastInternalRB = true;
                    } catch (Throwable t) {
                        SessionImpl.sessionLogger.log(Level.SEVERE, "Exception on rollback after TransactionPrepareStateFAILEDException " + jmqXid, t);
                        throw xae;
                    }
                } else {
                    if (!insyncstate) {
                        try {
                            _session.setInSyncState();
                        } catch (Throwable t) {
                            SessionImpl.sessionLogger.log(Level.SEVERE, "Exception on setting sync state on TransactionPrepareStateFAILEDException " + jmqXid, t);
                            throw xae;
                        }
                    }
                    try {
                        _session.rollbackAfterReceiveCommit(jmqXid);
                        xae = new XAException(XAException.XA_RBROLLBACK);
                        xae.initCause(jmse);
                        lastInternalRBCache.put(this, jmqXid);
                        lastInternalRB = true;
                    } catch (Throwable t) {
                        SessionImpl.sessionLogger.log(Level.SEVERE, "Exception on rollback after TransactionPrepareStateFAILEDException " + jmqXid, t);
                        throw xae;
                    } finally {
                        if (!insyncstate) {
                            _session.releaseInSyncState();
                        }
                    }
                }
            } else {
                xae = new XAException(XAException.XAER_RMERR);
                xae.initCause(jmse);
            }
        }
        throw xae;
    }
    // update the resource state
    resourceState = PREPARED;
    return result;
}
Also used : JMQXid(com.sun.messaging.jmq.util.JMQXid)

Example 37 with JMQXid

use of com.sun.messaging.jmq.util.JMQXid in project openmq by eclipse-ee4j.

the class XAResourceImpl method prepare.

/**
 * two-phase commit prepare for HA.
 */
@Override
public synchronized int prepare(Xid foreignXid) throws XAException {
    // result code
    int result = XA_OK;
    // this.twoPhasePrepared = false;
    JMQXid jmqXid = null;
    if (_connection.isConnectedToHABroker) {
        jmqXid = new JMQXid(foreignXid);
    }
    try {
        // two phase commit
        this.prepare(foreignXid, false, false);
    } catch (XAException xae) {
        if (_connection.isConnectedToHABroker) {
            checkPrepareStatus(xae, jmqXid);
        } else {
            // non HA -- propagate exception
            throw xae;
        }
    }
    if (isXATracking()) {
        xaTable.put(jmqXid, XA_PREPARE);
    }
    return result;
}
Also used : JMQXid(com.sun.messaging.jmq.util.JMQXid)

Example 38 with JMQXid

use of com.sun.messaging.jmq.util.JMQXid in project openmq by eclipse-ee4j.

the class XAResourceImpl method start.

/**
 * Starts work on behalf of a transaction branch specified in <code>foreignXid</code>.
 *
 * If TMJOIN is specified, the start applies to joining a transaction previously seen by the resource manager. If
 * TMRESUME is specified, the start applies to resuming a suspended transaction specified in the parameter
 * <code>foreignXid</code>.
 *
 * If neither TMJOIN nor TMRESUME is specified and the transaction specified by <code>foreignXid</code> has previously
 * been seen by the resource manager, the resource manager throws the XAException exception with XAER_DUPID error code.
 *
 * @param foreignXid A global transaction identifier to be associated with the resource.
 *
 * @param flags One of TMNOFLAGS, TMJOIN, or TMRESUME.
 *
 * @exception XAException An error has occurred. Possible exceptions are XA_RB*, XAER_RMERR, XAER_RMFAIL, XAER_DUPID,
 * XAER_OUTSIDE, XAER_NOTA, XAER_INVAL, or XAER_PROTO.
 */
@Override
public void start(Xid foreignXid, int flags) throws XAException {
    if (_logger.isLoggable(Level.FINE)) {
        _logger.fine(_lgrPrefix + "(" + this.hashCode() + ") Start   " + printXid(foreignXid) + printFlags(flags));
    }
    // convert to jmq xid
    JMQXid jmqXid = new JMQXid(foreignXid);
    if (lastInternalRB) {
        lastInternalRBCache.remove(this);
        lastInternalRB = false;
    }
    if (Debug.debug) {
        Debug.println("*=*=*=*=*=*=*=*=*=*=XAR:start:flags=" + flags + "\txid=\n" + jmqXid.toString());
    }
    try {
        _session.switchOnXATransaction();
        _transaction = _session.transaction;
        _transaction.startXATransaction(flags, jmqXid);
        if (!isResume(flags)) {
            XAResourceMap.register(jmqXid, this, isJoin(flags));
        }
        currentJMQXid = jmqXid;
    } catch (JMSException jmse) {
        // Debug.println("*=*=*=*=*=*=*=*=*=*=XAR:startXAException");
        Debug.printStackTrace(jmse);
        XAException xae = new XAException(XAException.XAER_RMFAIL);
        xae.initCause(jmse);
        throw xae;
    }
    // update the resource state
    resourceState = STARTED;
}
Also used : JMQXid(com.sun.messaging.jmq.util.JMQXid)

Example 39 with JMQXid

use of com.sun.messaging.jmq.util.JMQXid in project openmq by eclipse-ee4j.

the class TransactionManagerConfig method doRollbackCommit.

public void doRollbackCommit(String transactionID, boolean rollback) throws MBeanException {
    try {
        long longTid = 0;
        if (transactionID == null) {
            throw new Exception("Null transaction ID");
        }
        try {
            longTid = Long.parseLong(transactionID);
        } catch (Exception e) {
            throw new Exception("Invalid transaction ID: " + transactionID);
        }
        TransactionUID tid = new TransactionUID(longTid);
        TransactionList[] tls = Globals.getDestinationList().getTransactionList(null);
        TransactionList tl = null;
        TransactionState ts = null;
        for (int i = 0; i < tls.length; i++) {
            tl = tls[i];
            if (tl == null) {
                continue;
            }
            ts = tl.retrieveState(tid);
            if (ts == null) {
                continue;
            }
            break;
        }
        if (ts == null) {
            throw new Exception(rb.getString(rb.E_NO_SUCH_TRANSACTION, tid));
        }
        if (ts.getState() != TransactionState.PREPARED) {
            throw new Exception(rb.getString(rb.E_TRANSACTION_NOT_PREPARED, tid));
        }
        JMQXid xid = tl.UIDToXid(tid);
        if (xid == null) {
            throw new Exception(rb.getString(rb.E_INTERNAL_BROKER_ERROR, "Could not find Xid for " + tid));
        }
        PacketRouter pr = Globals.getPacketRouter(0);
        if (pr == null) {
            throw new Exception(rb.getString(rb.E_INTERNAL_BROKER_ERROR, "Could not locate Packet Router"));
        }
        TransactionHandler thandler = (TransactionHandler) pr.getHandler(PacketType.ROLLBACK_TRANSACTION);
        if (thandler == null) {
            throw new Exception(rb.getString(rb.E_INTERNAL_BROKER_ERROR, "Could not locate Transaction Handler"));
        }
        if (rollback) {
            thandler.doRollback(tl, tid, xid, null, ts, null, null, RollbackReason.ADMIN);
        } else {
            thandler.doCommit(tl, tid, xid, Integer.valueOf(XAResource.TMNOFLAGS), ts, null, false, null, null);
        }
    } catch (Exception e) {
        String opName;
        if (rollback) {
            opName = TransactionOperations.ROLLBACK;
        } else {
            opName = TransactionOperations.COMMIT;
        }
        handleOperationException(opName, e);
    }
}
Also used : TransactionUID(com.sun.messaging.jmq.jmsserver.data.TransactionUID) TransactionState(com.sun.messaging.jmq.jmsserver.data.TransactionState) PacketRouter(com.sun.messaging.jmq.jmsserver.data.PacketRouter) TransactionHandler(com.sun.messaging.jmq.jmsserver.data.handlers.TransactionHandler) TransactionList(com.sun.messaging.jmq.jmsserver.data.TransactionList) JMQXid(com.sun.messaging.jmq.util.JMQXid) MBeanException(javax.management.MBeanException)

Aggregations

JMQXid (com.sun.messaging.jmq.util.JMQXid)39 TransactionUID (com.sun.messaging.jmq.jmsserver.data.TransactionUID)13 TransactionState (com.sun.messaging.jmq.jmsserver.data.TransactionState)9 TransactionList (com.sun.messaging.jmq.jmsserver.data.TransactionList)6 BrokerException (com.sun.messaging.jmq.jmsserver.util.BrokerException)6 XidImpl (com.sun.messaging.jmq.util.XidImpl)4 JMSException (jakarta.jms.JMSException)4 Hashtable (java.util.Hashtable)4 XAException (javax.transaction.xa.XAException)4 JMSRASessionAdapter (com.sun.messaging.jms.ra.api.JMSRASessionAdapter)3 IOException (java.io.IOException)3 HashMap (java.util.HashMap)3 Iterator (java.util.Iterator)3 Map (java.util.Map)3 BrokerAddress (com.sun.messaging.jmq.jmsserver.core.BrokerAddress)2 TransactionBroker (com.sun.messaging.jmq.jmsserver.data.TransactionBroker)2 TransactionHandler (com.sun.messaging.jmq.jmsserver.data.handlers.TransactionHandler)2 PartitionedStore (com.sun.messaging.jmq.jmsserver.persist.api.PartitionedStore)2 UnknownTransactionException (com.sun.messaging.jmq.jmsserver.util.UnknownTransactionException)2 SelectorFormatException (com.sun.messaging.jmq.util.selector.SelectorFormatException)2