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();
}
}
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();
}
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;
}
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);
}
}
}
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);
}
}
}
Aggregations