in qpid-jms-client/src/main/java/org/apache/qpid/jms/JmsLocalTransactionContext.java [259:336]
private void doRollback(boolean startNewTx) throws JMSException {
lock.writeLock().lock();
try {
if (transactionInfo == null) {
return;
}
LOG.debug("Rollback: {}", transactionInfo.getId());
final JmsTransactionId oldTransactionId = transactionInfo.getId();
final JmsTransactionInfo nextTx;
if (startNewTx) {
nextTx = getNextTransactionInfo();
} else {
nextTx = null;
}
try {
connection.rollback(transactionInfo, nextTx, new ProviderSynchronization() {
@Override
public void onPendingSuccess() {
reset();
JmsLocalTransactionContext.this.transactionInfo = nextTx;
}
@Override
public void onPendingFailure(ProviderException cause) {
reset();
JmsLocalTransactionContext.this.transactionInfo = nextTx;
}
});
if (listener != null) {
try {
listener.onTransactionRolledBack();
} catch (Throwable error) {
LOG.trace("Local TX listener error ignored: {}", error);
}
try {
if (startNewTx) {
listener.onTransactionStarted();
}
} catch (Throwable error) {
LOG.trace("Local TX listener error ignored: {}", error);
}
}
} catch (JMSException cause) {
LOG.info("Rollback failed for transaction: {}", oldTransactionId);
if (listener != null) {
try {
listener.onTransactionRolledBack();
} catch (Throwable error) {
LOG.trace("Local TX listener error ignored: {}", error);
}
}
throw cause;
} finally {
try {
// If the provider failed to start a new transaction there will not be
// a current provider transaction id present, so we attempt to create
// one to recover our state.
if (startNewTx && nextTx.getId().getProviderTxId() == null) {
begin();
}
} catch (Exception e) {
// TODO
// At this point the transacted session is now unrecoverable, we should
// probably close it.
LOG.info("Failed to start new Transaction after failed rollback of: {}", oldTransactionId);
}
}
} finally {
lock.writeLock().unlock();
}
}