use of org.apache.activemq.artemis.core.transaction.impl.TransactionImpl in project activemq-artemis by apache.
the class DuplicateCacheTest method testDuplicateNonPersistent.
@Test
public void testDuplicateNonPersistent() throws Exception {
createStorage();
DuplicateIDCache cache = new DuplicateIDCacheImpl(new SimpleString("test"), 2000, journal, false);
TransactionImpl tx = new TransactionImpl(journal);
for (int i = 0; i < 5000; i++) {
byte[] bytes = RandomUtil.randomBytes();
cache.addToCache(bytes, tx);
}
tx.commit();
for (int i = 0; i < 5000; i++) {
byte[] bytes = RandomUtil.randomBytes();
cache.addToCache(bytes, null);
}
}
use of org.apache.activemq.artemis.core.transaction.impl.TransactionImpl in project activemq-artemis by apache.
the class DuplicateCacheTest method testDuplicate.
@Test
public void testDuplicate() throws Exception {
createStorage();
DuplicateIDCache cache = new DuplicateIDCacheImpl(new SimpleString("test"), 2000, journal, true);
TransactionImpl tx = new TransactionImpl(journal);
for (int i = 0; i < 5000; i++) {
byte[] bytes = RandomUtil.randomBytes();
cache.addToCache(bytes, tx);
}
tx.commit();
tx = new TransactionImpl(journal);
for (int i = 0; i < 5000; i++) {
byte[] bytes = RandomUtil.randomBytes();
cache.addToCache(bytes, tx);
}
tx.commit();
byte[] id = RandomUtil.randomBytes();
Assert.assertFalse(cache.contains(id));
cache.addToCache(id, null);
Assert.assertTrue(cache.contains(id));
cache.deleteFromCache(id);
final CountDownLatch latch = new CountDownLatch(1);
OperationContextImpl.getContext().executeOnCompletion(new IOCallback() {
@Override
public void done() {
latch.countDown();
}
@Override
public void onError(int errorCode, String errorMessage) {
}
}, true);
Assert.assertTrue(latch.await(1, TimeUnit.MINUTES));
Assert.assertFalse(cache.contains(id));
}
use of org.apache.activemq.artemis.core.transaction.impl.TransactionImpl in project activemq-artemis by apache.
the class PostOfficeImpl method checkDuplicateID.
private boolean checkDuplicateID(final Message message, final RoutingContext context, boolean rejectDuplicates, AtomicBoolean startedTX) throws Exception {
// Check the DuplicateCache for the Bridge first
Object bridgeDup = message.removeExtraBytesProperty(Message.HDR_BRIDGE_DUPLICATE_ID);
if (bridgeDup != null) {
// if the message is being sent from the bridge, we just ignore the duplicate id, and use the internal one
byte[] bridgeDupBytes = (byte[]) bridgeDup;
DuplicateIDCache cacheBridge = getDuplicateIDCache(BRIDGE_CACHE_STR.concat(context.getAddress(message).toString()));
if (context.getTransaction() == null) {
context.setTransaction(new TransactionImpl(storageManager));
startedTX.set(true);
}
if (!cacheBridge.atomicVerify(bridgeDupBytes, context.getTransaction())) {
context.getTransaction().rollback();
startedTX.set(false);
message.decrementRefCount();
return false;
}
} else {
// if used BridgeDuplicate, it's not going to use the regular duplicate
// since this will would break redistribution (re-setting the duplicateId)
byte[] duplicateIDBytes = message.getDuplicateIDBytes();
DuplicateIDCache cache = null;
boolean isDuplicate = false;
if (duplicateIDBytes != null) {
cache = getDuplicateIDCache(context.getAddress(message));
isDuplicate = cache.contains(duplicateIDBytes);
if (rejectDuplicates && isDuplicate) {
ActiveMQServerLogger.LOGGER.duplicateMessageDetected(message);
String warnMessage = "Duplicate message detected - message will not be routed. Message information:" + message.toString();
if (context.getTransaction() != null) {
context.getTransaction().markAsRollbackOnly(new ActiveMQDuplicateIdException(warnMessage));
}
message.decrementRefCount();
return false;
}
}
if (cache != null && !isDuplicate) {
if (context.getTransaction() == null) {
// We need to store the duplicate id atomically with the message storage, so we need to create a tx for this
context.setTransaction(new TransactionImpl(storageManager));
startedTX.set(true);
}
cache.addToCache(duplicateIDBytes, context.getTransaction(), false);
}
}
return true;
}
use of org.apache.activemq.artemis.core.transaction.impl.TransactionImpl 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.impl.TransactionImpl 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;
}
Aggregations