use of com.sun.messaging.jmq.jmsserver.data.TransactionUID in project openmq by eclipse-ee4j.
the class TransactionHandler method doRemoteRollback.
private void doRemoteRollback(TransactionList translist, TransactionUID id, int nextState) throws BrokerException {
if (nextState != TransactionState.ROLLEDBACK) {
throw new BrokerException("Unexpected state " + nextState + " for transactionUID:" + id);
}
if (!translist.hasRemoteBroker(id)) {
return;
}
if (Globals.getClusterBroadcast().getClusterVersion() < ClusterBroadcast.VERSION_410) {
return;
}
TransactionBroker[] bas = null;
try {
bas = translist.getClusterTransactionBrokers(id);
if (DEBUG_CLUSTER_TXN) {
StringBuilder buf = new StringBuilder();
buf.append("Rollback transaction ").append(id).append(", remote brokers");
for (TransactionBroker ba : bas) {
buf.append("\n\t").append(ba);
}
logger.log(logger.INFO, buf.toString());
}
BrokerAddress addr = null;
UID tranpid = null;
if (Globals.getDestinationList().isPartitionMode()) {
tranpid = translist.getPartitionedStore().getPartitionID();
}
for (int i = 0; i < bas.length; i++) {
if (Globals.getDestinationList().isPartitionMode()) {
if (tranpid.equals(bas[i].getBrokerAddress().getStoreSessionUID())) {
continue;
}
} else if (bas[i].getBrokerAddress() == Globals.getMyAddress()) {
continue;
}
addr = bas[i].getCurrentBrokerAddress();
if (addr == Globals.getMyAddress()) {
if (DEBUG_CLUSTER_TXN) {
logger.log(logger.INFO, "Transaction remote broker current address " + bas[i].toString() + " is my address, TUID=" + id);
}
} else {
if (DEBUG_CLUSTER_TXN) {
logger.log(logger.INFO, "Transaction remote broker current address " + addr + ", TUID=" + id);
}
}
try {
if (addr != null) {
Globals.getClusterBroadcast().acknowledgeMessage2P(addr, (SysMessageID[]) null, (ConsumerUID[]) null, ClusterBroadcast.MSG_ROLLEDBACK, null, Long.valueOf(id.longValue()), tranpid, false, false);
} else {
throw new BrokerDownException(br.getKString(br.X_CLUSTER_UNICAST_UNREACHABLE, bas[i]), Status.GONE);
}
} catch (BrokerException e) {
String emsg = br.getKString(br.W_ROLLBACK_TXN_NOTIFY_REMOTE_BKR_FAIL, bas[i], id);
if (e.getStatusCode() == Status.GONE || e.getStatusCode() == Status.TIMEOUT || e instanceof BrokerDownException) {
logger.log(logger.WARNING, emsg + ": " + e.getMessage());
} else {
logger.logStack(logger.WARNING, emsg, e);
}
}
}
} catch (Exception e) {
StringBuilder buf = new StringBuilder();
if (bas != null) {
for (TransactionBroker ba : bas) {
buf.append("\n\t").append(ba);
}
}
String emsg = br.getKString(br.W_ROLLBACK_TXN_NOTIFY_RMEOTE_BKRS_FAIL, buf.toString(), id);
logger.logStack(logger.WARNING, emsg, e);
}
}
use of com.sun.messaging.jmq.jmsserver.data.TransactionUID in project openmq by eclipse-ee4j.
the class TransactionHandler method convertPacketTid.
/**
* Convert the transaction ID on an iMQ 2.0 packet to the new style.
*/
public static void convertPacketTid(IMQConnection con, Packet p) {
long messagetid = p.getTransactionID();
HashMap tidMap = (HashMap) con.getClientData(IMQConnection.TRANSACTION_IDMAP);
if (tidMap == null) {
// No transactions have been started yet. Can't convert ID
return;
}
// Lookup old style ID in table
TransactionUID id = (TransactionUID) tidMap.get(Long.valueOf(messagetid));
if (id == null) {
return;
}
// Convert the old ID to the corresponding new ID
p.setTransactionID(id.longValue());
}
use of com.sun.messaging.jmq.jmsserver.data.TransactionUID in project openmq by eclipse-ee4j.
the class TransactionHandler method checkRefRequeued.
private boolean checkRefRequeued(TransactionList translist, TransactionUID id, PacketReference ref, SysMessageID sysid) throws BrokerException {
HashMap addrmap = translist.retrieveAckBrokerAddresses(id);
BrokerAddress oldAddr = (BrokerAddress) addrmap.get(sysid);
if (ref == null && DL.isLocked(null, sysid)) {
logger.log(logger.WARNING, "Message " + sysid + ((oldAddr == null) ? "" : " (" + oldAddr + ")") + " is in takeover, TUID=" + id);
return true;
}
if (ref == null) {
logger.log(logger.WARNING, Globals.getBrokerResources().getKString(BrokerResources.X_MESSAGE_REF_GONE, sysid) + " " + ((oldAddr == null) ? "" : " (" + oldAddr + ")") + ", TUID=" + id);
return false;
}
if (ref.isOverrided()) {
return true;
}
BrokerAddress currAddr = ref.getBrokerAddress();
if (oldAddr == null && currAddr == null) {
return false;
}
if ((oldAddr == null && currAddr != null) || (oldAddr != null && currAddr == null)) {
return true;
}
if (!oldAddr.equals(currAddr)) {
return true;
}
UID oldUID = oldAddr.getBrokerSessionUID();
UID currUID = currAddr.getBrokerSessionUID();
if (oldUID == null || currUID == null) {
return false;
}
if (!oldUID.equals(currUID)) {
return true;
}
return false;
}
use of com.sun.messaging.jmq.jmsserver.data.TransactionUID in project openmq by eclipse-ee4j.
the class ClusterTransactionManager method replayTransactionEvent.
@Override
void replayTransactionEvent(TransactionEvent txnEvent, HashSet dstLoadedSet) throws BrokerException, IOException {
if (Store.getDEBUG()) {
Globals.getLogger().log(Logger.DEBUG, getPrefix() + " replayTransactionEvent");
}
ClusterTransactionEvent clusterTxnEvent = (ClusterTransactionEvent) txnEvent;
// replay to store on commit
ClusterTransaction clusterTxn = clusterTxnEvent.clusterTransaction;
int state = clusterTxn.getState();
TransactionUID tid = clusterTxn.getTid();
if (clusterTxnEvent.getSubType() == ClusterTransactionEvent.Type2PPrepareEvent) {
// in prepared txn store and resetting the transaction log
if (incompleteStored.containsKey(tid)) {
if (Store.getDEBUG()) {
String msg = getPrefix() + " found matching txn in prepared store on replay " + clusterTxn;
Globals.getLogger().log(Logger.DEBUG, msg);
}
} else {
addToIncompleteUnstored(clusterTxn);
}
} else if (clusterTxnEvent.getSubType() == ClusterTransactionEvent.Type2PCompleteEvent) {
// we are completing a transaction
// the transaction could be
// a) unstored (prepare replayed earlier)
// b) stored incomplete (prepare occurred before last checkpoint,
// completion not written to prepared store yet)
// This should therefore be the last entry in log.
// c) stored complete (prepare occurred before last checkpoint,
// and failure occurred after completion stored in prepared store
BaseTransaction existingWork = null;
if (incompleteUnstored.containsKey(tid)) {
// a) unstored (prepare replayed earlier)
if (state == TransactionState.ROLLEDBACK) {
existingWork = removeFromIncompleteUnstored(tid);
} else if (state == TransactionState.COMMITTED) {
existingWork = incompleteUnstored.get(tid);
existingWork.getTransactionDetails().setState(state);
existingWork.getTransactionState().setState(state);
}
} else if (incompleteStored.containsKey(tid)) {
// b) stored incomplete (prepare occurred before last checkpoint,
// completion not written to prepared store yet)
existingWork = removeFromIncompleteStored(tid);
updateStoredState(tid, state);
addToCompleteStored(existingWork);
} else if (completeStored.containsKey(tid)) {
// c) stored complete (prepare occurred before last checkpoint,
// and failure occurred after completion stored in prepared store
existingWork = completeStored.get(tid);
}
if (existingWork != null) {
if (state == TransactionState.COMMITTED) {
transactionLogManager.transactionLogReplayer.replayTransactionWork(existingWork.getTransactionWork(), tid, dstLoadedSet);
}
} else {
logger.log(Logger.ERROR, "Could not find prepared work for completing two-phase transaction " + clusterTxn.getTid());
}
}
}
use of com.sun.messaging.jmq.jmsserver.data.TransactionUID in project openmq by eclipse-ee4j.
the class FileStore method initTxnLogger.
// Initialize txn logging class
@Override
public boolean initTxnLogger() throws BrokerException {
boolean storeNeedsRestart = false;
if (removeStore || !Globals.txnLogEnabled()) {
return storeNeedsRestart;
}
logger.log(logger.INFO, BrokerResources.I_TXNLOG_ENABLED);
// create txn log writers
String filename = null;
try {
SizeString filesize = config.getSizeProperty(TXNLOG_FILE_SIZE_PROP, DEFAULT_TXNLOG_FILE_SIZE);
filename = MSG_LOG_FILENAME;
msgLogWriter = new FileTransactionLogWriter(rootDir, filename, filesize.getBytes());
msgLogWriter.setCheckPointListener(this);
filename = ACK_LOG_FILENAME;
ackLogWriter = new FileTransactionLogWriter(rootDir, filename, filesize.getBytes());
ackLogWriter.setCheckPointListener(this);
if (resetMessage || resetStore) {
msgLogWriter.reset();
ackLogWriter.reset();
txnLoggerInited = true;
return storeNeedsRestart;
}
} catch (IOException ex) {
logger.logStack(Logger.ERROR, BrokerResources.E_CREATE_TXNLOG_FILE_FAILED, filename, ex);
throw new BrokerException(br.getString(BrokerResources.E_CREATE_TXNLOG_FILE_FAILED, filename), ex);
}
// reconstruct persistence store if needed
try {
TransactionLogRecord rec;
byte[] data;
ByteArrayInputStream bis;
DataInputStream dis;
// Keep track of loaded dst
HashSet dstLoadedSet = new HashSet();
// Check to see if we need to process log files
if (msgLogWriter.playBackRequired()) {
storeNeedsRestart = true;
logger.log(logger.FORCE, BrokerResources.I_PROCESS_MSG_TXNLOG);
// All destinations need to be loaded
Globals.getCoreLifecycle().initDestinations();
Globals.getCoreLifecycle().initSubscriptions();
int count = 0;
Iterator itr = msgLogWriter.iterator();
while (itr.hasNext()) {
// Keep track the number of records processed
count++;
// Read in the messages
rec = (TransactionLogRecord) itr.next();
int recType = rec.getType();
if (recType != TransactionLogType.PRODUCE_TRANSACTION) {
// Shouldn't happens
logger.log(logger.ERROR, BrokerResources.E_PROCESS_TXNLOG_RECORD_FAILED, String.valueOf(rec.getSequence()), "record type " + recType + " is invalid");
continue;
}
data = rec.getBody();
bis = new ByteArrayInputStream(data);
dis = new DataInputStream(bis);
// Transaction ID
long tid = dis.readLong();
String tidStr = String.valueOf(tid);
logger.log(logger.FORCE, BrokerResources.I_PROCESS_TXNLOG_RECORD, tidStr, String.valueOf(recType));
// Process all msgs in the txn
processTxnRecMsgPart(dis, dstLoadedSet);
// Check to see if we need to commit the txn
if (tid > 0) {
TransactionUID tuid = new TransactionUID(tid);
TransactionState state = tidList.getTransactionState(tuid);
if (state.getState() != TransactionState.NULL && state.getState() != TransactionState.COMMITTED) {
logger.log(logger.FORCE, BrokerResources.I_COMMIT_TXNLOG_RECORD, tidStr);
tidList.updateTransactionState(tuid, state, false);
}
}
dis.close();
bis.close();
}
logger.log(logger.FORCE, BrokerResources.I_LOAD_MSG_TXNLOG, String.valueOf(count));
logger.flush();
}
// of record, we'll just store it the same file for simplicity.
if (ackLogWriter.playBackRequired()) {
storeNeedsRestart = true;
logger.log(logger.FORCE, BrokerResources.I_PROCESS_ACK_TXNLOG);
// All destinations need to be loaded
Globals.getCoreLifecycle().initDestinations();
Globals.getCoreLifecycle().initSubscriptions();
int count = 0;
Iterator itr = ackLogWriter.iterator();
while (itr.hasNext()) {
// Keep track the number of records processed
count++;
// Read in the acks or msgs & acks
rec = (TransactionLogRecord) itr.next();
int recType = rec.getType();
if (!(recType == TransactionLogType.CONSUME_TRANSACTION || recType == TransactionLogType.PRODUCE_AND_CONSUME_TRANSACTION)) {
// shouldn't happens
logger.log(logger.ERROR, BrokerResources.E_PROCESS_TXNLOG_RECORD_FAILED, String.valueOf(rec.getSequence()), "record type " + recType + " is invalid");
continue;
}
data = rec.getBody();
bis = new ByteArrayInputStream(data);
dis = new DataInputStream(bis);
// Transaction ID
long tid = dis.readLong();
String tidStr = String.valueOf(tid);
logger.log(logger.FORCE, BrokerResources.I_PROCESS_TXNLOG_RECORD, tidStr, String.valueOf(recType));
if (recType == TransactionLogType.PRODUCE_AND_CONSUME_TRANSACTION) {
// Process all msgs in the txn first!
processTxnRecMsgPart(dis, dstLoadedSet);
}
// Process all acks in the txn
processTxnRecAckPart(dis, dstLoadedSet);
// Check to see if we need to commit the txn
TransactionUID tuid = new TransactionUID(tid);
TransactionState state = tidList.getTransactionState(tuid);
if (state.getState() != TransactionState.NULL && state.getState() != TransactionState.COMMITTED) {
logger.log(logger.FORCE, BrokerResources.I_COMMIT_TXNLOG_RECORD, tidStr);
tidList.updateTransactionState(tuid, state, false);
}
dis.close();
bis.close();
}
logger.log(logger.FORCE, BrokerResources.I_LOAD_ACK_TXNLOG, String.valueOf(count));
logger.flush();
}
if (storeNeedsRestart) {
// Now unload all the destinations that we've loaded so msgs can be routed correctly later on by the broker
Iterator itr = dstLoadedSet.iterator();
while (itr.hasNext()) {
Destination d = (Destination) itr.next();
// Sync changes to disk
syncDestination(d);
d.unload(true);
}
dstLoadedSet = null;
// Sync changes to txn tables
tidList.sync(null);
tidList.syncTransactionAck(null);
// Reset the txn log after the store is updated & synced
msgLogWriter.reset();
ackLogWriter.reset();
logger.log(logger.FORCE, BrokerResources.I_RECONSTRUCT_STORE_DONE);
logger.flush();
}
} catch (Throwable t) {
logger.logStack(Logger.ERROR, BrokerResources.E_RECONSTRUCT_STORE_FAILED, t);
throw new BrokerException(br.getString(BrokerResources.E_RECONSTRUCT_STORE_FAILED), t);
}
txnLoggerInited = true;
return storeNeedsRestart;
}
Aggregations