Search in sources :

Example 1 with TransactionManagerImpl

use of com.sun.messaging.bridge.service.jms.tx.TransactionManagerImpl in project openmq by eclipse-ee4j.

the class Link method runTransacted.

private void runTransacted() throws Throwable {
    long msgCount = 0;
    long receiveTimeout = 0L;
    if (_parent.supportTransactionTimeout()) {
        receiveTimeout = (((long) _parent.getTransactionTimeout()) / (long) 2) * 1000;
    }
    int consecutiveThrowables = 0;
    while (_state != LinkState.STOPPING && _state != LinkState.STOPPED) {
        if (Thread.currentThread().isInterrupted()) {
            throw new InterruptedException(_jbr.getKString(_jbr.X_LINK_INTERRUPTED, this.toString()));
        }
        Transaction transaction = null;
        XAResourceHandle srh = new XAResourceHandle(false);
        XAResourceHandle trh = new XAResourceHandle(true);
        Message m = null;
        MessageHeaders srcmhs = null;
        String mid = null;
        Throwable currentThrowable = null;
        _branchProducer = null;
        _targetCurrentDestinationName = null;
        try {
            if (_sourceConnException) {
                closeSource();
                initSource();
                resume(false);
            }
            if (_targetConnException) {
                closeTarget();
                if (_targetStayConnected) {
                    initTarget();
                }
            }
            srh.xar = ((XASession) _sourceSession).getXAResource();
            if (_logger.isLoggable(Level.FINE)) {
                _logger.log(Level.FINE, "BEGIN transaction in " + this);
            }
            try {
                _tm.begin();
            } catch (Exception e) {
                currentThrowable = e;
                _logger.log(Level.SEVERE, "Unable to start transaction in" + this, e);
                _sourceConnException = true;
                _targetConnException = true;
                continue;
            }
            try {
                transaction = _tm.getTransaction();
            } catch (Exception e) {
                currentThrowable = e;
                _logger.log(Level.SEVERE, "Exception to get transaction in" + this, e);
                _sourceConnException = true;
                _targetConnException = true;
                continue;
            }
            if (_logger.isLoggable(Level.FINE)) {
                _logger.log(Level.FINE, "enlist source in transaction " + transaction + " in " + this);
            }
            if (!doEnlistAndRollbackOnError(transaction, _tm, srh)) {
                currentThrowable = srh.ex;
                continue;
            }
            try {
                if (_logger.isLoggable(Level.FINE)) {
                    _logger.log(Level.FINE, "Receiving(" + receiveTimeout + ") message from source in transaction " + transaction + " in " + this);
                }
                if (_fi.FAULT_INJECTION) {
                    _fi.setLogger(_logger);
                    _fi.checkFaultAndThrowException(FaultInjection.FAULT_RECEIVE_1, null, "jakarta.jms.JMSException", true);
                }
                m = _consumer.receive(receiveTimeout);
                if (m == null) {
                    try {
                        String logmsg = ((receiveTimeout > 0L) ? _jbr.getKString(_jbr.W_SOURCE_CONN_CLOSED_OR_RECEIVE_TIMEOUT, this.toString()) : _jbr.getKString(_jbr.W_SOURCE_CONN_CLOSED, this.toString()));
                        _logger.log(Level.WARNING, logmsg);
                    } catch (Throwable t) {
                    }
                    try {
                        _tm.rollback();
                    } catch (Throwable t1) {
                        try {
                            if (receiveTimeout == 0L) {
                                _logger.log(Level.FINE, "Unable to rollback transaction " + transaction + " on closed source connection or receive() timeout ", t1);
                            } else {
                                logWarning("Unable to rollback transaction " + transaction + " on closed source connection or receive() timeout ", t1);
                            }
                        } catch (Throwable t) {
                        }
                    }
                    continue;
                }
                msgCount++;
                if (_logger.isLoggable(Level.FINE)) {
                    _logger.log(Level.FINE, "Received message " + m + " from source in transaction " + transaction + " in " + this + ", msgCount=" + msgCount);
                }
                if (_fi.FAULT_INJECTION) {
                    _fi.setLogger(_logger);
                    _fi.checkFaultAndThrowException(FaultInjection.FAULT_RECEIVE_2, null, "jakarta.jms.JMSException", true);
                }
            } catch (Throwable t) {
                currentThrowable = t;
                logWarning("Exception in receiving message in " + this, t);
                try {
                    _tm.rollback();
                } catch (Throwable t1) {
                    logWarning("Exception on rollback transaction " + transaction + " on receiving failure", t1);
                }
                continue;
            }
            if (!isTransactionActive(transaction, _tm)) {
                continue;
            }
            srcmhs = MessageHeaders.getMessageHeaders(m);
            mid = srcmhs.mid;
            long ttl = srcmhs.expiration;
            if (ttl != 0L) {
                ttl = ttl - System.currentTimeMillis();
            }
            if (ttl < 0) {
                handleExpiredMessage(m, mid, transaction, _tm, srh);
                continue;
            }
            if (!isTransactionActive(transaction, _tm)) {
                continue;
            }
            if (!_targetStayConnected) {
                try {
                    initTarget();
                } catch (Exception e) {
                    _logger.log(Level.SEVERE, "Unable to connect to target in " + this, e);
                    try {
                        _tm.rollback();
                    } catch (Throwable t1) {
                        _logger.log(Level.WARNING, "Unable to rollback transaction " + transaction + " on init target failure for message " + mid + " in " + this, t1);
                    }
                    throw e;
                }
            }
            if (!isTransactionActive(transaction, _tm)) {
                continue;
            }
            Message sm = null;
            String midSent = null;
            try {
                sm = handleMessageTransformer(m, srcmhs);
            } catch (Throwable t) {
                _logger.log(Level.WARNING, _jbr.getString(_jbr.W_STOP_LINK_BECAUSE_OF, this, t.getMessage()), t);
                throw t;
            }
            if (sm == null) {
                _logger.log(Level.WARNING, _jbr.getString(_jbr.W_CONSUME_NO_TRANSFER, mid, this));
                if (!isTransactionActive(transaction, _tm)) {
                    continue;
                }
            } else {
                if (_targetCF.isEmbeded() && _sourceCF.isEmbeded()) {
                    trh.xar = srh.xar;
                } else {
                    trh.xar = ((XASession) _targetSession).getXAResource();
                    if (!(_tm instanceof TransactionManagerImpl) && trh.xar.getClass().getName().equals(srh.xar.getClass().getName())) {
                        trh.xar = new XAResourceImpl(trh.xar);
                        _logger.log(Level.INFO, "Use XAResource wrapper " + trh.xar + " for target XAResource " + trh.xar.getClass().getName());
                    }
                    if (_logger.isLoggable(Level.FINE)) {
                        _logger.log(Level.FINE, "enlist target in transaction " + transaction + " in " + this);
                    }
                    if (!doEnlistAndRollbackOnError(transaction, _tm, trh)) {
                        currentThrowable = trh.ex;
                        continue;
                    }
                }
                try {
                    if (_logger.isLoggable(Level.FINE)) {
                        _logger.log(Level.FINE, "Sending message " + mid + " to target in transaction " + transaction + " in " + this);
                    }
                    if (_fi.FAULT_INJECTION) {
                        _fi.setLogger(_logger);
                        _fi.checkFaultAndThrowException(FaultInjection.FAULT_SEND_1, null, "jakarta.jms.JMSException", true);
                    }
                    MessageProducer producer = _producer;
                    if (_branchProducer != null) {
                        producer = _branchProducer;
                    }
                    if (!getTargetCurrentDestinationName().equals(toDestinationName(producer.getDestination()))) {
                        throw new BridgeException("Unexpected target producer's destination name " + toDestinationName(producer.getDestination()) + ": not match current target destination name " + getTargetCurrentDestinationName());
                    }
                    try {
                        if (_parent.needTagBridgeName()) {
                            _parent.tagBridgeName(sm, _sourceSession.createMessage());
                        }
                        producer.send(sm, srcmhs.deliverymode, srcmhs.priority, ttl);
                        midSent = sm.getJMSMessageID();
                    } finally {
                        if (_branchProducer != null) {
                            try {
                                _branchProducer.close();
                            } catch (Throwable t) {
                                _logger.log(Level.WARNING, "Closing temporary target producer failed: " + t.getMessage() + " in " + this, t);
                            } finally {
                                _branchProducer = null;
                            }
                        }
                        MessageHeaders.resetMessageHeaders(m, srcmhs);
                    }
                    if (_logger.isLoggable(Level.FINE)) {
                        _logger.log(Level.FINE, "Sent message " + mid + " to target in transaction " + transaction + " in " + this);
                    }
                    if (_fi.FAULT_INJECTION) {
                        _fi.setLogger(_logger);
                        _fi.checkFaultAndThrowException(FaultInjection.FAULT_SEND_2, null, "jakarta.jms.JMSException", true);
                    }
                } catch (Throwable t) {
                    currentThrowable = t;
                    _logger.log(Level.SEVERE, "Unable to send message " + mid + " to target in " + this, t);
                    try {
                        _tm.rollback();
                    } catch (Throwable t1) {
                        _logger.log(Level.WARNING, "Unable to rollback transaction " + transaction + " on send failure for message " + mid + " in " + this, t1);
                    }
                    continue;
                }
                if (!isTransactionActive(transaction, _tm)) {
                    continue;
                }
                if (_logger.isLoggable(Level.FINE)) {
                    _logger.log(Level.FINE, "delist " + trh + " in transaction " + transaction + " in " + this);
                }
                if (trh.xar != srh.xar) {
                    if (!doDelistAndRollbackOnError(transaction, _tm, trh)) {
                        currentThrowable = trh.ex;
                        continue;
                    }
                }
            }
            if (!isTransactionActive(transaction, _tm)) {
                continue;
            }
            if (_logger.isLoggable(Level.FINE)) {
                _logger.log(Level.FINE, "delist " + srh + " in transaction " + transaction + " in " + this);
            }
            if (!doDelistAndRollbackOnError(transaction, _tm, srh)) {
                currentThrowable = srh.ex;
                continue;
            }
            if (_logger.isLoggable(Level.FINE)) {
                _logger.log(Level.FINE, "COMMIT transaction " + transaction + " for message " + mid + " in " + this);
            }
            try {
                _tm.commit();
                String[] param = { mid, midSent, this.toString() };
                if (_parent.logMessageTransfer()) {
                    _logger.log(Level.INFO, _jbr.getString(_jbr.I_MESSAGE_TRANSFER_SUCCESS, param));
                } else if (_logger.isLoggable(Level.FINE)) {
                    _logger.log(Level.FINE, _jbr.getString(_jbr.I_MESSAGE_TRANSFER_SUCCESS, param));
                }
            } catch (RollbackException e) {
                _logger.log(Level.WARNING, "RollbackException on commit transaction " + transaction + " for message " + mid + " in " + this, e);
                sendToDMQ(m, mid, DMQ.DMQReason.COMMIT_FAILURE, e);
                continue;
            } catch (HeuristicMixedException e) {
                _logger.log(Level.WARNING, "HeuristicMixedException on commit transaction " + transaction + " for message " + mid + " in " + this, e);
                sendToDMQ(m, mid, DMQ.DMQReason.COMMIT_FAILURE, e);
                continue;
            } catch (HeuristicRollbackException e) {
                _logger.log(Level.WARNING, "HeuristicRollbackException on commit transaction " + transaction + " for message " + mid + " in " + this, e);
                sendToDMQ(m, mid, DMQ.DMQReason.COMMIT_FAILURE, e);
                continue;
            } catch (Throwable t) {
                currentThrowable = t;
                _logger.log(Level.SEVERE, "Failed to commit transaction " + transaction + " for message " + mid + " in " + this, t);
                sendToDMQ(m, mid, DMQ.DMQReason.COMMIT_FAILURE, t);
                continue;
            }
        } finally {
            doFinally(transaction, _tm, srh, trh);
            if (currentThrowable == null) {
                consecutiveThrowables = 0;
            } else {
                consecutiveThrowables++;
                if (consecutiveThrowables > MAX_CONSECUTIVE_THROWABLES) {
                    throw new RuntimeException("Maximum consecutive exceptions exceeded", currentThrowable);
                }
            }
        }
    }
}
Also used : Message(jakarta.jms.Message) HeuristicRollbackException(jakarta.transaction.HeuristicRollbackException) RollbackException(jakarta.transaction.RollbackException) BridgeException(com.sun.messaging.bridge.api.BridgeException) JMSException(jakarta.jms.JMSException) HeuristicRollbackException(jakarta.transaction.HeuristicRollbackException) RollbackException(jakarta.transaction.RollbackException) HeuristicMixedException(jakarta.transaction.HeuristicMixedException) BridgeException(com.sun.messaging.bridge.api.BridgeException) HeuristicRollbackException(jakarta.transaction.HeuristicRollbackException) Transaction(jakarta.transaction.Transaction) TransactionManagerImpl(com.sun.messaging.bridge.service.jms.tx.TransactionManagerImpl) HeuristicMixedException(jakarta.transaction.HeuristicMixedException) MessageProducer(jakarta.jms.MessageProducer)

Example 2 with TransactionManagerImpl

use of com.sun.messaging.bridge.service.jms.tx.TransactionManagerImpl in project openmq by eclipse-ee4j.

the class JMSBridge method initTransactionManager.

private void initTransactionManager() throws Exception {
    synchronized (_initLock) {
        if (_tma != null) {
            return;
        }
        String c = _bc.getTransactionManagerClass();
        if (c == null) {
            c = "com.sun.messaging.bridge.service.jms.tx.TransactionManagerImpl";
        }
        _logger.log(Level.INFO, _jbr.getString(_jbr.I_USE_TM_ADAPTER_CLASS, c));
        Class cs = Class.forName(c);
        _tma = (TransactionManagerAdapter) cs.getDeclaredConstructor().newInstance();
        _tma.setLogger(_logger);
        Properties props = _bc.getTransactionManagerProps();
        if (props == null) {
            props = new Properties();
        }
        if (_tma instanceof TransactionManagerImpl) {
            props.setProperty("tmname", _bc.getIdentityName() + ":" + _name);
            props.setProperty("txlogDir", _bc.getRootDir());
            props.setProperty("txlogSuffix", _name);
            props.setProperty("jmsbridge", _name);
            if (_bc.isJDBCStoreType()) {
                props.setProperty("txlogType", TxLog.JDBCTYPE);
                ((TransactionManagerImpl) _tma).setJDBCStore((JMSBridgeStore) _bc.getJDBCStore(Bridge.JMS_TYPE));
            }
            _supportTransactionTimeout = false;
        }
        _logger.log(Level.INFO, _jbr.getString(_jbr.I_INIT_TM_WITH_PROPS, props.toString()));
        _tma.init(props, _reset);
        _tm = _tma.getTransactionManager();
        if (!(_tma instanceof TransactionManagerImpl)) {
            _logger.log(Level.INFO, _jbr.getString(_jbr.I_SET_TM_TIMEOUT, _transactionTimeout));
            _tm.setTransactionTimeout(_transactionTimeout);
            _supportTransactionTimeout = true;
        }
    }
}
Also used : TransactionManagerImpl(com.sun.messaging.bridge.service.jms.tx.TransactionManagerImpl) Properties(java.util.Properties)

Aggregations

TransactionManagerImpl (com.sun.messaging.bridge.service.jms.tx.TransactionManagerImpl)2 BridgeException (com.sun.messaging.bridge.api.BridgeException)1 JMSException (jakarta.jms.JMSException)1 Message (jakarta.jms.Message)1 MessageProducer (jakarta.jms.MessageProducer)1 HeuristicMixedException (jakarta.transaction.HeuristicMixedException)1 HeuristicRollbackException (jakarta.transaction.HeuristicRollbackException)1 RollbackException (jakarta.transaction.RollbackException)1 Transaction (jakarta.transaction.Transaction)1 Properties (java.util.Properties)1