public void rollback(Xid xid) throws HeuristicMixedException, HeuristicCommitException, IllegalStateException, SystemException { try { this.terminator.rollback(xid); } catch (XAException xaex) { switch (xaex.errorCode) { case XAException.XA_HEURRB: break; case XAException.XA_HEURMIX: throw new HeuristicMixedException(); case XAException.XA_HEURCOM: throw new HeuristicCommitException(); default: logger.error("Unknown state in rollingback transaction phase.", xaex); throw new SystemException(); } } catch (RuntimeException rex) { logger.error("Unknown state in rollingback transaction phase.", rex); throw new SystemException(); } }
/** * Rollback the current XA transaction. Transaction will not timeout while changing status but rather by some * extra logic that will manually throw the exception after doing as much cleanup as possible. * * @param transaction the transaction to rollback. * @param interestedResources resources that should be rolled back. * @throws HeuristicCommitException when all resources committed instead. * @throws HeuristicMixedException when some resources committed and some rolled back. * @throws bitronix.tm.internal.BitronixSystemException when an internal error occured. */ public void rollback(BitronixTransaction transaction, List<XAResourceHolderState> interestedResources) throws HeuristicMixedException, HeuristicCommitException, BitronixSystemException { XAResourceManager resourceManager = transaction.getResourceManager(); transaction.setStatus(Status.STATUS_ROLLING_BACK); this.interestedResources.clear(); this.interestedResources.addAll(interestedResources); try { executePhase(resourceManager, true); } catch (PhaseException ex) { logFailedResources(ex); transaction.setStatus(Status.STATUS_UNKNOWN); throwException("transaction failed during rollback of " + transaction, ex, interestedResources.size()); } if (log.isDebugEnabled()) { log.debug("rollback executed on resources " + Decoder.collectResourcesNames(rolledbackResources)); } // Some resources might have failed the 2nd phase of 2PC. // Only resources which successfully rolled back should be registered in the journal, the other // ones should be picked up by the recoverer. // Not interested resources have to be included as well since they returned XA_RDONLY and they // don't participate in phase 2: the TX succeded for them. Set<String> rolledbackAndNotInterestedUniqueNames = new HashSet<String>(); rolledbackAndNotInterestedUniqueNames.addAll(collectResourcesUniqueNames(rolledbackResources)); List<XAResourceHolderState> notInterestedResources = collectNotInterestedResources(resourceManager.getAllResources(), interestedResources); rolledbackAndNotInterestedUniqueNames.addAll(collectResourcesUniqueNames(notInterestedResources)); if (log.isDebugEnabled()) { List<XAResourceHolderState> rolledbackAndNotInterestedResources = new ArrayList<XAResourceHolderState>(); rolledbackAndNotInterestedResources.addAll(rolledbackResources); rolledbackAndNotInterestedResources.addAll(notInterestedResources); log.debug("rollback succeeded on resources " + Decoder.collectResourcesNames(rolledbackAndNotInterestedResources)); } transaction.setStatus(Status.STATUS_ROLLEDBACK, rolledbackAndNotInterestedUniqueNames); }
private void throwException(String message, PhaseException phaseException, int totalResourceCount) throws HeuristicMixedException, HeuristicCommitException { List<Exception> exceptions = phaseException.getExceptions(); List<XAResourceHolderState> resources = phaseException.getResourceStates(); boolean hazard = false; List<XAResourceHolderState> heuristicResources = new ArrayList<XAResourceHolderState>(); List<XAResourceHolderState> errorResources = new ArrayList<XAResourceHolderState>(); for (int i = 0; i < exceptions.size(); i++) { Exception ex = exceptions.get(i); XAResourceHolderState resourceHolder = resources.get(i); if (ex instanceof XAException) { XAException xaEx = (XAException) ex; switch (xaEx.errorCode) { case XAException.XA_HEURHAZ: hazard = true; case XAException.XA_HEURCOM: case XAException.XA_HEURRB: case XAException.XA_HEURMIX: heuristicResources.add(resourceHolder); break; default: errorResources.add(resourceHolder); } } else errorResources.add(resourceHolder); } if (!hazard && heuristicResources.size() == totalResourceCount) throw new BitronixHeuristicCommitException(message + ":" + " all resource(s) " + Decoder.collectResourcesNames(heuristicResources) + " improperly unilaterally committed", phaseException); else throw new BitronixHeuristicMixedException(message + ":" + (errorResources.size() > 0 ? " resource(s) " + Decoder.collectResourcesNames(errorResources) + " threw unexpected exception" : "") + (errorResources.size() > 0 && heuristicResources.size() > 0 ? " and" : "") + (heuristicResources.size() > 0 ? " resource(s) " + Decoder.collectResourcesNames(heuristicResources) + " improperly unilaterally committed" + (hazard ? " (or hazard happened)" : "") : ""), phaseException); }
public void commit() throws HeuristicMixedException, HeuristicRollbackException, SystemException, RemoteException { TransactionImpl transaction = TransactionImpl.this; synchronized (transaction) { TransactionStatus transactionStatus = transaction.transactionStatus; if (transactionStatus.isActive()) { throw new IllegalStateException(); } else if (transactionStatus.isMarkedRollbackOnly()) { throw new IllegalStateException(); } else if (transactionStatus.isRolledBack()) { throw new HeuristicRollbackException(); } else if (transactionStatus.isRollingBack()) { try { this.rollback(); throw new HeuristicRollbackException(); } catch (IllegalStateException ex) { SystemException exception = new SystemException(); exception.initCause(ex); throw exception; } catch (HeuristicCommitException e) { return; } } else if (transactionStatus.isCommitted()) { return; } transaction.setTransactionCompleting(true); try { if (transactionStatus.isPrepared()) { transactionStatus.setStatusCommiting(); transactionStatistic.fireCommittingTransaction(transaction); transactionLogger.updateTransaction(transaction); } else if (transactionStatus.isCommitting()) { // ignore } else { throw new IllegalStateException(); } transaction.participantCommit(); if (transactionStatus.isCommitting()) { transactionStatus.setStatusCommitted(); transactionStatistic.fireCommittedTransaction(transaction); transactionLogger.completeTransaction(transaction); } else if (transactionStatus.isCommitted()) { // ignore } else { throw new IllegalStateException(); } } finally { transaction.afterCompletion(); } } }
public void rollback() throws HeuristicMixedException, HeuristicCommitException, SystemException, RemoteException { TransactionImpl transaction = TransactionImpl.this; synchronized (transaction) { TransactionStatus transactionStatus = transaction.transactionStatus; if (transactionStatus.isActive()) { throw new IllegalStateException(); } else if (transactionStatus.isMarkedRollbackOnly()) { throw new IllegalStateException(); } else if (transactionStatus.isCommitted()) { throw new IllegalStateException(); } else if (transactionStatus.isRolledBack()) { return; } try { if (transactionStatus.isActive() || transactionStatus.isMarkedRollbackOnly()) { transactionStatus.setStatusRollingback(); transactionStatistic.fireRollingBackTransaction(transaction); transactionLogger.updateTransaction(transaction); } else if (transactionStatus.isPrepareFail() || transactionStatus.isPrepared()) { transactionStatus.setStatusRollingback(); transactionStatistic.fireRollingBackTransaction(transaction); transactionLogger.updateTransaction(transaction); } else if (transactionStatus.isRollingBack()) { // ignore } else if (transactionStatus.isCommitting() || transactionStatus.isCommitFail()) { transactionStatus.setStatusRollingback(); transactionStatistic.fireRollingBackTransaction(transaction); transactionLogger.updateTransaction(transaction); } else { throw new IllegalStateException(); } transaction.setTransactionCompleting(true); transaction.participantRollback(); if (transactionStatus.isRollingBack()) { transactionStatus.setStatusRolledback(); transactionStatistic.fireRolledbackTransaction(transaction); } else if (transactionStatus.isRolledBack()) { // ignore } else { throw new IllegalStateException(); } transactionLogger.completeTransaction(transaction); } finally { transaction.afterCompletion(); } } }
public void rollback(Xid xid) throws HeuristicMixedException, HeuristicCommitException, IllegalStateException, SystemException;
public void rollback(Xid xid) throws HeuristicMixedException, HeuristicCommitException, IllegalStateException, SystemException { }
/** * Drive the subordinate transaction to commit. It must have previously * been prepared. * * @return true, if the transaction was fully committed, false if there was a transient error * * @throws IllegalStateException thrown if the transaction has not been prepared * or is unknown. * @throws HeuristicMixedException thrown if a heuristic mixed outcome occurs * (where some participants committed whilst others rolled back). * @throws HeuristicRollbackException thrown if the transaction rolled back. * @throws SystemException thrown if some other error occurs. */ public boolean doCommit() throws IllegalStateException, HeuristicMixedException, HeuristicRollbackException, HeuristicCommitException, SystemException;
/** * Drive the subordinate transaction to roll back. It need not have been previously * prepared. * * @throws IllegalStateException thrown if the transaction is not known by the * system or has been previously terminated. * @throws HeuristicMixedException thrown if a heuristic mixed outcome occurs * (can only happen if the transaction was previously prepared and then only if * some participants commit whilst others roll back). * @throws HeuristicCommitException thrown if the transaction commits (can only * happen if it was previously prepared). * @throws SystemException thrown if any other error occurs. */ public void doRollback() throws IllegalStateException, HeuristicMixedException, HeuristicCommitException, HeuristicRollbackException, SystemException;
public void rollback() throws HeuristicMixedException, HeuristicCommitException, SystemException, RemoteException;