Search in sources :

Example 36 with Transaction

use of org.apache.activemq.artemis.core.transaction.Transaction in project activemq-artemis by apache.

the class ActiveMQServerControlImpl method commitPreparedTransaction.

@Override
public synchronized boolean commitPreparedTransaction(final String transactionAsBase64) throws Exception {
    checkStarted();
    clearIO();
    try {
        List<Xid> xids = resourceManager.getPreparedTransactions();
        for (Xid xid : xids) {
            if (XidImpl.toBase64String(xid).equals(transactionAsBase64)) {
                Transaction transaction = resourceManager.removeTransaction(xid);
                transaction.commit(false);
                long recordID = server.getStorageManager().storeHeuristicCompletion(xid, true);
                storageManager.waitOnOperations();
                resourceManager.putHeuristicCompletion(recordID, xid, true);
                return true;
            }
        }
        return false;
    } finally {
        blockOnIO();
    }
}
Also used : Xid(javax.transaction.xa.Xid) Transaction(org.apache.activemq.artemis.core.transaction.Transaction)

Example 37 with Transaction

use of org.apache.activemq.artemis.core.transaction.Transaction in project activemq-artemis by apache.

the class PageSubscriptionImpl method ack.

@Override
public void ack(final PagedReference reference) throws Exception {
    // Need to do the ACK and counter atomically (inside a TX) or the counter could get out of sync
    Transaction tx = new TransactionImpl(this.store);
    ackTx(tx, reference);
    tx.commit();
}
Also used : Transaction(org.apache.activemq.artemis.core.transaction.Transaction) TransactionImpl(org.apache.activemq.artemis.core.transaction.impl.TransactionImpl)

Example 38 with Transaction

use of org.apache.activemq.artemis.core.transaction.Transaction in project activemq-artemis by apache.

the class Redistributor method handle.

@Override
public synchronized HandleStatus handle(final MessageReference reference) throws Exception {
    if (!active) {
        return HandleStatus.BUSY;
    } else if (reference.getMessage().getGroupID() != null) {
        // we shouldn't redistribute with message groups return NO_MATCH so other messages can be delivered
        return HandleStatus.NO_MATCH;
    }
    final Transaction tx = new TransactionImpl(storageManager);
    final Pair<RoutingContext, Message> routingInfo = postOffice.redistribute(reference.getMessage(), queue, tx);
    if (routingInfo == null) {
        return HandleStatus.BUSY;
    }
    if (!reference.getMessage().isLargeMessage()) {
        postOffice.processRoute(routingInfo.getB(), routingInfo.getA(), false);
        ackRedistribution(reference, tx);
    } else {
        active = false;
        executor.execute(new Runnable() {

            @Override
            public void run() {
                try {
                    postOffice.processRoute(routingInfo.getB(), routingInfo.getA(), false);
                    ackRedistribution(reference, tx);
                    synchronized (Redistributor.this) {
                        active = true;
                        count++;
                        queue.deliverAsync();
                    }
                } catch (Exception e) {
                    try {
                        tx.rollback();
                    } catch (Exception e2) {
                        // Nothing much we can do now
                        ActiveMQServerLogger.LOGGER.failedToRollback(e2);
                    }
                }
            }
        });
    }
    return HandleStatus.HANDLED;
}
Also used : RoutingContext(org.apache.activemq.artemis.core.server.RoutingContext) Transaction(org.apache.activemq.artemis.core.transaction.Transaction) Message(org.apache.activemq.artemis.api.core.Message) TransactionImpl(org.apache.activemq.artemis.core.transaction.impl.TransactionImpl)

Example 39 with Transaction

use of org.apache.activemq.artemis.core.transaction.Transaction in project activemq-artemis by apache.

the class MQTTPublishManager method sendInternal.

/**
 * Sends a message either on behalf of the client or on behalf of the broker (Will Messages)
 * @param messageId
 * @param topic
 * @param qos
 * @param payload
 * @param retain
 * @param internal if true means on behalf of the broker (skips authorisation) and does not return ack.
 * @throws Exception
 */
void sendInternal(int messageId, String topic, int qos, ByteBuf payload, boolean retain, boolean internal) throws Exception {
    synchronized (lock) {
        Message serverMessage = MQTTUtil.createServerMessageFromByteBuf(session, topic, retain, qos, payload);
        if (qos > 0) {
            serverMessage.setDurable(MQTTUtil.DURABLE_MESSAGES);
        }
        if (qos < 2 || !state.getPubRec().contains(messageId)) {
            if (qos == 2 && !internal)
                state.getPubRec().add(messageId);
            Transaction tx = session.getServerSession().newTransaction();
            try {
                if (internal) {
                    session.getServer().getPostOffice().route(serverMessage, tx, true);
                } else {
                    session.getServerSession().send(tx, serverMessage, true, false);
                }
                if (retain) {
                    boolean reset = payload instanceof EmptyByteBuf || payload.capacity() == 0;
                    session.getRetainMessageManager().handleRetainedMessage(serverMessage, topic, reset, tx);
                }
                tx.commit();
            } catch (Throwable t) {
                logger.warn(t.getMessage(), t);
                tx.rollback();
                throw t;
            }
            createMessageAck(messageId, qos, internal);
        }
    }
}
Also used : ICoreMessage(org.apache.activemq.artemis.api.core.ICoreMessage) Message(org.apache.activemq.artemis.api.core.Message) Transaction(org.apache.activemq.artemis.core.transaction.Transaction) EmptyByteBuf(io.netty.buffer.EmptyByteBuf)

Example 40 with Transaction

use of org.apache.activemq.artemis.core.transaction.Transaction in project activemq-artemis by apache.

the class AMQConsumer method acknowledge.

/**
 * The acknowledgement in openwire is done based on intervals.
 * We will iterate through the list of delivering messages at {@link ServerConsumer#getDeliveringReferencesBasedOnProtocol(boolean, Object, Object)}
 * and add those to the Transaction.
 * Notice that we will start a new transaction on the cases where there is no transaction.
 */
public void acknowledge(MessageAck ack) throws Exception {
    MessageId first = ack.getFirstMessageId();
    MessageId last = ack.getLastMessageId();
    if (first == null) {
        first = last;
    }
    // if it's browse only, nothing to be acked, we just remove the lists
    boolean removeReferences = !serverConsumer.isBrowseOnly();
    if (ack.isRedeliveredAck() || ack.isDeliveredAck() || ack.isExpiredAck()) {
        removeReferences = false;
    }
    List<MessageReference> ackList = serverConsumer.getDeliveringReferencesBasedOnProtocol(removeReferences, first, last);
    acquireCredit(ack.getMessageCount());
    if (removeReferences) {
        Transaction originalTX = session.getCoreSession().getCurrentTransaction();
        Transaction transaction;
        if (originalTX == null) {
            transaction = session.getCoreSession().newTransaction();
        } else {
            transaction = originalTX;
        }
        if (ack.isIndividualAck() || ack.isStandardAck()) {
            for (MessageReference ref : ackList) {
                ref.acknowledge(transaction);
            }
        } else if (ack.isPoisonAck()) {
            for (MessageReference ref : ackList) {
                Throwable poisonCause = ack.getPoisonCause();
                if (poisonCause != null) {
                    ref.getMessage().putStringProperty(OpenWireMessageConverter.AMQ_MSG_DLQ_DELIVERY_FAILURE_CAUSE_PROPERTY, new SimpleString(poisonCause.toString()));
                }
                ref.getQueue().sendToDeadLetterAddress(transaction, ref);
            }
        }
        if (originalTX == null) {
            transaction.commit(true);
        }
    }
    if (ack.isExpiredAck()) {
        for (MessageReference ref : ackList) {
            ref.getQueue().expire(ref);
        }
    }
}
Also used : Transaction(org.apache.activemq.artemis.core.transaction.Transaction) SimpleString(org.apache.activemq.artemis.api.core.SimpleString) MessageReference(org.apache.activemq.artemis.core.server.MessageReference) MessageId(org.apache.activemq.command.MessageId)

Aggregations

Transaction (org.apache.activemq.artemis.core.transaction.Transaction)52 TransactionImpl (org.apache.activemq.artemis.core.transaction.impl.TransactionImpl)24 MessageReference (org.apache.activemq.artemis.core.server.MessageReference)14 Test (org.junit.Test)14 SimpleString (org.apache.activemq.artemis.api.core.SimpleString)13 Xid (javax.transaction.xa.Xid)12 Queue (org.apache.activemq.artemis.core.server.Queue)11 ArrayList (java.util.ArrayList)10 Message (org.apache.activemq.artemis.api.core.Message)10 ActiveMQException (org.apache.activemq.artemis.api.core.ActiveMQException)9 Map (java.util.Map)8 StorageManager (org.apache.activemq.artemis.core.persistence.StorageManager)8 HashMap (java.util.HashMap)7 PageSubscriptionCounter (org.apache.activemq.artemis.core.paging.cursor.PageSubscriptionCounter)7 PageSubscription (org.apache.activemq.artemis.core.paging.cursor.PageSubscription)6 BindingsTransactionImpl (org.apache.activemq.artemis.core.transaction.impl.BindingsTransactionImpl)6 AtomicLong (java.util.concurrent.atomic.AtomicLong)5 List (java.util.List)4 NoSuchElementException (java.util.NoSuchElementException)4 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)4