TransactionAcknowledgement[] tas = tae.getAcks();
Set s = new LinkedHashSet();
ackEntry entry = null, value = null;
for (int i = 0; i < tas.length; i++) {
SysMessageID sysid = tas[i].getSysMessageID();
com.sun.messaging.jmq.jmsserver.core.ConsumerUID uid = tas[i].getConsumerUID();
com.sun.messaging.jmq.jmsserver.core.ConsumerUID suid = tas[i].getStoredConsumerUID();
if (suid == null) suid = uid;
synchronized(deliveredMessages) {
entry = new ackEntry(sysid, uid, null);
value = (ackEntry)deliveredMessages.get(entry);
if (value == null) {
if (DEBUG_CLUSTER_TXN) {
logger.log(logger.INFO,
"["+sysid+":"+uid+"] not found in rolling back remote transaction "+tid);
}
continue;
}
if (value.getTUID() == null || !value.getTUID().equals(tid)) {
if (DEBUG_CLUSTER_TXN) {
logger.log(logger.INFO,
"["+sysid+":"+uid+"] with TUID="+value.getTUID()+
", in rolling back remote transaction "+tid);
}
continue;
}
if (consumers.get(uid) == null) {
deliveredMessages.remove(entry);
cleanupPendingConsumerUID(uid, sysid);
s.add(tas[i]);
} else {
value.setTUID(null);
}
}
}
Iterator itr = s.iterator();
while (itr.hasNext()) {
TransactionAcknowledgement ta = (TransactionAcknowledgement)itr.next();
SysMessageID sysid = ta.getSysMessageID();
com.sun.messaging.jmq.jmsserver.core.ConsumerUID cuid = ta.getConsumerUID();
com.sun.messaging.jmq.jmsserver.core.ConsumerUID suid = ta.getStoredConsumerUID();
if (suid == null) suid = cuid;
PacketReference ref = Destination.get(sysid);
if (ref == null) {
if (DEBUG_CLUSTER_TXN) {
logger.log(logger.INFO,
"["+sysid+":"+cuid+"] reference not found in rolling back remote transaction "+tid);
}
continue;
}
ref.removeInDelivery(suid);
ref.getDestination().forwardOrphanMessage(ref, suid);
}
} //tas != null
try {
Globals.getTransactionList().removeRemoteTransactionAck(tid);
} catch (Exception e) {
logger.log(logger.WARNING,
"Unable to remove transaction ack for rolledback transaction "+tid+": "+e.getMessage());
}
try {
Globals.getTransactionList().removeRemoteTransactionID(tid, true);
} catch (Exception e ) {
logger.log(logger.WARNING,
"Unable to remove rolledback remote transaction "+tid+": "+e.getMessage());
}
return;
}
int cLogRecordCount = 0;
ArrayList cLogDstList = null;
ArrayList cLogMsgList = null;
ArrayList cLogIntList = null;
if (ackType == ClusterBroadcast.MSG_ACKNOWLEDGED) {
if (DEBUG_CLUSTER_TXN) {
logger.log(logger.INFO, "Committing remote transaction "+tid + " from "+txnHomeBroker);
}
if (!Globals.getTransactionList().updateRemoteTransactionState(tid,
TransactionState.COMMITTED, (sysids == null), true, true)) {
if (DEBUG_CLUSTER_TXN) {
logger.log(logger.INFO, "Remote transaction "+tid + " already committed, from "+txnHomeBroker);
}
return;
}
boolean done = true;
if (translist.getRecoveryRemoteTransactionAcks(tid) != null) {
done = commitRecoveryRemoteTransaction(tid, txnHomeBroker);
}
RemoteTransactionAckEntry tae = translist.getRemoteTransactionAcks(tid);
if (tae == null) {
logger.log(logger.INFO,
"No non-recovery transaction acks to process for committing remote transaction "+tid);
} else if (tae.processed()) {
logger.log(logger.INFO,
"No more transaction acks to process for committing remote transaction "+tid);
} else {
boolean found = false;
TransactionAcknowledgement[] tas = tae.getAcks();
for (int i = 0; i < tas.length; i++) {
SysMessageID sysid = tas[i].getSysMessageID();
com.sun.messaging.jmq.jmsserver.core.ConsumerUID cuid = tas[i].getConsumerUID();
if (sysids != null && !found) {
if (sysid.equals(sysids[0]) && cuid.equals(cuids[0])) {
found = true;
}
}
String dstName = null;
if (Globals.txnLogEnabled()) {
if (cLogDstList == null) {
cLogDstList = new ArrayList();
cLogMsgList = new ArrayList();
cLogIntList = new ArrayList();
}
PacketReference ref = Destination.get(sysid);
if (ref != null && !ref.isDestroyed() && !ref.isInvalid()) {
Destination dst = Destination.getDestination(ref.getDestinationUID());
dstName = dst.getUniqueName();
}
}
if (acknowledgeMessageFromRemote(ackType, sysid, cuid, optionalProps)) {
if (dstName != null) {
// keep track for consumer txn log
com.sun.messaging.jmq.jmsserver.core.ConsumerUID suid = tas[i].getStoredConsumerUID();
if (suid == null) suid = cuid;
cLogRecordCount++;
cLogDstList.add(dstName);
cLogMsgList.add(sysid);
cLogIntList.add(suid);
}
} else {
done = false;
}
}
// notify that message acks have been written to store
if(Globals.isNewTxnLogEnabled())
{
Globals.getStore().loggedCommitWrittenToMessageStore(tid, BaseTransaction.REMOTE_TRANSACTION_TYPE);
}
if (sysids != null && !found) {
logger.log(logger.ERROR,
"Internal Error: ["+sysids[0]+":"+cuids[0]+"] not found in remote transaction " +tid);
done = false;
}
} //tae != null
if (done) {
try {
Globals.getTransactionList().removeRemoteTransactionAck(tid);
} catch (Exception e) {
logger.logStack(logger.WARNING,
"Unable to remove transaction ack for committed remote transaction "+tid, e);
}
try {
Globals.getTransactionList().removeRemoteTransactionID(tid, true);
} catch (Exception e ) {
logger.logStack(logger.WARNING,
"Unable to remove committed remote transaction "+tid, e);
}
} else if (Globals.getHAEnabled()) {
throw new BrokerException(
"Remote transaction processing incomplete, TUID="+tid);
}
// log to txn log if enabled
try {
if (Globals.txnLogEnabled() && (cLogRecordCount > 0) ) {
// Log all acks for consuming txn
ByteArrayOutputStream bos = new ByteArrayOutputStream(
(cLogRecordCount * (32 + SysMessageID.ID_SIZE + 8)) + 12);
DataOutputStream dos = new DataOutputStream(bos);
dos.writeLong(tid.longValue()); // Transaction ID (8 bytes)
dos.writeInt(cLogRecordCount); // Number of acks (4 bytes)
for (int i = 0; i < cLogRecordCount; i++) {
String dst = (String)cLogDstList.get(i);
dos.writeUTF(dst); // Destination
SysMessageID sysid = (SysMessageID)cLogMsgList.get(i);
sysid.writeID(dos); // SysMessageID
long intid =
((com.sun.messaging.jmq.jmsserver.core.ConsumerUID)
cLogIntList.get(i)).longValue();
dos.writeLong(intid); // ConsumerUID
}