use of com.sun.messaging.jmq.jmsserver.data.TransactionUID in project openmq by eclipse-ee4j.
the class LocalTransactionManager method replayTransactionEvent.
@Override
void replayTransactionEvent(TransactionEvent txnEvent, HashSet dstLoadedSet) throws BrokerException, IOException {
if (Store.getDEBUG()) {
Globals.getLogger().log(Logger.DEBUG, getPrefix() + " replayTransactionEvent");
}
LocalTransactionEvent localTxnEvent = (LocalTransactionEvent) txnEvent;
// replay to store on commit
LocalTransaction localTxn = localTxnEvent.localTransaction;
int state = localTxn.getState();
TransactionUID tid = localTxn.getTid();
if (localTxnEvent.getSubType() == LocalTransactionEvent.Type1PCommitEvent) {
// one phase commit
// Just replay it now
transactionLogManager.transactionLogReplayer.replayTransactionWork(localTxn.getTransactionWork(), tid, dstLoadedSet);
} else if (localTxnEvent.getSubType() == LocalTransactionEvent.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 " + localTxn;
Globals.getLogger().log(Logger.DEBUG, msg);
}
} else {
addToIncompleteUnstored(localTxn);
}
} else if (localTxnEvent.getSubType() == LocalTransactionEvent.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)
existingWork = removeFromIncompleteUnstored(tid);
} 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 " + localTxn.getTid());
}
}
}
use of com.sun.messaging.jmq.jmsserver.data.TransactionUID in project openmq by eclipse-ee4j.
the class PreparedTxnStore method storeTransaction.
TransactionWorkInfo storeTransaction(BaseTransaction baseTxn, boolean sync) throws IOException, BrokerException {
TransactionUID id = baseTxn.getTid();
// loaded before this is called
if (transactionMap.containsKey(id)) {
String emsg = br.getKString(br.E_TRANSACTIONID_NOT_FOUND_IN_STORE, id) + ": " + storeName;
logger.log(logger.ERROR, emsg);
throw new BrokerException(emsg);
}
try {
byte[] data = baseTxn.writeToBytes();
int msgsize = data.length;
if (sync && Store.getDEBUG_SYNC()) {
String msg = " PreparedTxnStore storeTransaction sync " + baseTxn;
Globals.getLogger().log(Logger.DEBUG, msg);
}
TransactionWorkInfo info = null;
if (vrfile != null && (maxRecordSize == 0 || msgsize < maxRecordSize)) {
// store in vrfil
info = new TransactionWorkInfo(this, vrfile, baseTxn, data, sync);
} else {
// store in individual file
info = new TransactionWorkInfo(this, baseTxn, data, sync);
}
// cache it, make sure to use the cloned SysMessageID
transactionMap.put(info.getID(), info);
// increate destination message count and byte count
incrTxnCount(msgsize);
return info;
} catch (IOException e) {
logger.log(logger.ERROR, br.X_PERSIST_MESSAGE_FAILED, id.toString(), e);
throw e;
}
}
use of com.sun.messaging.jmq.jmsserver.data.TransactionUID in project openmq by eclipse-ee4j.
the class PreparedTxnStore method parseData.
// BEGIN: implement super class (RandomAccessStore) abstract method
/**
* parse the message and it's associated interest list from the given buffers. This is loaded from individual message
* files. Returns the sysMessageID.
*/
@Override
Object parseData(byte[] data, byte[] attachment) throws IOException {
TransactionWorkInfo minfo = new TransactionWorkInfo(this, data);
// if everything is ok, we cache it
// make sure to use the cloned SysMessageID
TransactionUID tid = minfo.getID();
transactionMap.put(tid, minfo);
return tid;
}
use of com.sun.messaging.jmq.jmsserver.data.TransactionUID in project openmq by eclipse-ee4j.
the class TidList method clear.
/**
* Clear all transactions that are NOT in the specified state.
*
* @param state State of transactions to spare
*/
void clear(int state, boolean sync) throws BrokerException {
boolean error = false;
Exception exception = null;
Iterator itr = tidMap.entrySet().iterator();
while (itr.hasNext()) {
try {
Map.Entry entry = (Map.Entry) itr.next();
TransactionUID tid = (TransactionUID) entry.getKey();
TransactionState ts = (TransactionState) entry.getValue();
// Remove if not in prepared state
if (ts.getState() != state) {
// XXX PERF 12/7/2001 This operation updates disk
// with every call.
itr.remove();
try {
txnAckList.removeAcks(tid, sync);
} catch (BrokerException e) {
// TxnAckList Logs error
error = true;
exception = e;
break;
}
}
} catch (RuntimeException e) {
error = true;
exception = e;
logger.log(logger.ERROR, br.X_CLEAR_TXN_NOTIN_STATE_FAILED, Integer.valueOf(state), e);
}
if (sync) {
sync(null);
}
}
if (!error) {
// We may have transactions left in the txnAckList that did not
// have an entry in the tidMap (maybe it was removed by a commit
// that never had a chance to complete processing the acks).
// Check for those "orphaned" ack transactions here.
TransactionUID[] tids = txnAckList.getAllTids();
for (int i = 0; i < tids.length; i++) {
TransactionInfo txnInfo = (TransactionInfo) tidMap.get(tids[i]);
if (txnInfo == null || txnInfo.getTransactionStateValue() != state) {
// Orphan. Remove from txnList
try {
txnAckList.removeAcks(tids[i], sync);
} catch (BrokerException e) {
// TxnAckList Logs error
error = true;
exception = e;
break;
}
}
}
}
// If we got an error just clear all transactions.
if (error) {
clearAll(sync);
throw new BrokerException(br.getString(br.X_CLEAR_TXN_NOTIN_STATE_FAILED, Integer.valueOf(state)), exception);
}
}
use of com.sun.messaging.jmq.jmsserver.data.TransactionUID in project openmq by eclipse-ee4j.
the class RaptorProtocol method receivedTransactionInfo.
public void receivedTransactionInfo(GPacket pkt, BrokerAddress sender, MessageBusCallback cb) {
ClusterTxnInfoInfo ii = ClusterTxnInfoInfo.newInstance(pkt, c);
BrokerAddress from = sender;
UID msgss = ii.getMessageStoreSessionUID();
if (msgss != null) {
from = (BrokerAddress) sender.clone();
from.setStoreSessionUID(msgss);
}
if (DEBUG_CLUSTER_TXN) {
logger.log(logger.INFO, Globals.getBrokerResources().getString(BrokerResources.I_RECEIVED_TXN_INFO, from.toString(), ii.toString()));
}
Long tid = ii.getTransactionID();
TransactionUID tuid = new TransactionUID(tid.longValue());
int s = ii.getTransactionState();
TransactionList tl = null;
TransactionState mystate = null;
Object[] oo = TransactionList.getTransListAndState(tuid, null, true, false);
if (oo != null) {
tl = (TransactionList) oo[0];
mystate = (TransactionState) oo[1];
}
if (!ii.isOwner() || (ii.isOwner() && from.equals(selfAddress))) {
if (mystate != null && mystate.getState() == TransactionState.COMMITTED) {
if (tl.getClusterTransactionBroker(tuid, from) != null) {
if (s == TransactionState.COMMITTED || (!ii.isOwner() && s == TransactionState.NULL)) {
if (DEBUG_CLUSTER_TXN) {
logger.log(logger.INFO, "Update broker " + from + " for committed cluster transaction " + tuid);
}
try {
tl.completeClusterTransactionBrokerState(tuid, TransactionState.COMMITTED, from, true);
if (!ii.isOwner() && s != TransactionState.NULL) {
sendClusterTransactionInfo(tuid, from, null);
}
} catch (Exception e) {
logger.logStack(logger.WARNING, "Unable to update transaction broker state for " + from + ", TUID=" + tuid, e);
if (!ii.isOwner()) {
return;
}
}
}
} else {
if (DEBUG_CLUSTER_TXN) {
logger.log(logger.INFO, "Broker " + from + " is not a transaction broker for TUID=" + tuid);
}
}
if (!ii.isOwner()) {
return;
}
}
}
if (s == TransactionState.NULL && !ii.isOwner()) {
return;
}
List<Object[]> list = TransactionList.getTransListsAndRemoteTranStates(tuid);
if (list == null && !ii.isOwner()) {
return;
}
if (list == null && ii.isOwner()) {
try {
if (ii.getWaitfor() != null && ii.isWaitedfor((selfAddress))) {
sendRemoteTransactionInfo(tuid, from, null, true);
return;
}
} catch (Exception e) {
logger.logStack(logger.WARNING, e.getMessage(), e);
return;
}
// for rollback pending unprepared
if (s != TransactionState.NULL) {
return;
}
}
int type = -1;
switch(s) {
case TransactionState.ROLLEDBACK:
case TransactionState.FAILED:
type = ClusterGlobals.MB_MSG_TXN_ROLLEDBACK;
break;
case TransactionState.NULL:
logger.log(logger.INFO, Globals.getBrokerResources().getKString(BrokerResources.I_REMOTE_TXN_PRESUMED_ROLLBACK, tuid, from));
type = ClusterGlobals.MB_MSG_TXN_ROLLEDBACK;
break;
case TransactionState.COMMITTED:
type = ClusterGlobals.MB_MSG_CONSUMED;
break;
default:
return;
}
try {
cb.processRemoteAck2P(null, null, type, null, tid, from);
if (s == TransactionState.COMMITTED && ii.isOwner()) {
BrokerAddress[] brokers = ii.getBrokers();
List waitfor = ii.getWaitfor();
if (brokers == null && waitfor == null) {
return;
}
if (waitfor != null) {
sendRemoteTransactionInfo(tuid, from, null, true);
}
}
} catch (Exception e) {
if (DEBUG_CLUSTER_TXN) {
logger.logStack(logger.WARNING, e.getMessage(), e);
} else {
logger.log(logger.WARNING, e.getMessage());
}
}
}
Aggregations