synchronized TxLog getTxLog() throws IOException { if (txLog.getRecordCount() > maxTxLogRecordCount) { if (txLog.getName().endsWith(txLog1FileName)) { txLog.switchToLogFile(txLogDir + separator + txLog2FileName); changeActiveLog(txLog2FileName); } else if (txLog.getName().endsWith(txLog2FileName)) { txLog.switchToLogFile(txLogDir + separator + txLog1FileName); changeActiveLog(txLog1FileName); } else { setTmNotOk( new Exception( "Unknown active tx log file[" + txLog.getName() + "], unable to switch.")); log.severe("Unknown active tx log file[" + txLog.getName() + "], unable to switch."); final IOException ex = new IOException( "Unknown txLogFile[" + txLog.getName() + "] not equals to either [" + txLog1FileName + "] or [" + txLog2FileName + "]"); throw logAndReturn("TM error accessing log file", ex); } } return txLog; }
void doCommit() throws XAException, SystemException { boolean onePhase = isOnePhase(); boolean readOnly = true; if (!onePhase) { // prepare status = Status.STATUS_PREPARING; LinkedList<Xid> preparedXids = new LinkedList<Xid>(); Iterator<ResourceElement> itr = resourceList.iterator(); while (itr.hasNext()) { ResourceElement re = itr.next(); if (!preparedXids.contains(re.getXid())) { preparedXids.add(re.getXid()); int vote = re.getResource().prepare(re.getXid()); if (vote == XAResource.XA_OK) { readOnly = false; } else if (vote == XAResource.XA_RDONLY) { re.setStatus(RS_READONLY); } else { // rollback tx status = Status.STATUS_MARKED_ROLLBACK; return; } } else { // set it to readonly, only need to commit once re.setStatus(RS_READONLY); } } status = Status.STATUS_PREPARED; } // commit if (!onePhase && readOnly) { status = Status.STATUS_COMMITTED; return; } if (!onePhase) { try { txManager.getTxLog().markAsCommitting(getGlobalId()); } catch (IOException e) { log.log(Level.SEVERE, "Error writing transaction log", e); txManager.setTmNotOk(); throw Exceptions.withCause( new SystemException("TM encountered a problem, " + " error writing transaction log"), e); } } status = Status.STATUS_COMMITTING; Iterator<ResourceElement> itr = resourceList.iterator(); while (itr.hasNext()) { ResourceElement re = itr.next(); if (re.getStatus() != RS_READONLY) { re.getResource().commit(re.getXid(), onePhase); } } status = Status.STATUS_COMMITTED; }
private void rollbackCommit(Thread thread, TransactionImpl tx) throws HeuristicMixedException, RollbackException, SystemException { try { tx.doRollback(); } catch (XAException e) { log.log( Level.SEVERE, "Unable to rollback marked transaction. " + "Some resources may be commited others not. " + "Neo4j kernel should be SHUTDOWN for " + "resource maintance and transaction recovery ---->", e); setTmNotOk(e); throw logAndReturn( "TM error tx rollback commit", Exceptions.withCause( new HeuristicMixedException( "Unable to rollback " + " ---> error code for rollback: " + e.errorCode), e)); } tx.doAfterCompletion(); txThreadMap.remove(thread); try { if (tx.isGlobalStartRecordWritten()) { getTxLog().txDone(tx.getGlobalId()); } } catch (IOException e) { log.log(Level.SEVERE, "Error writing transaction log", e); setTmNotOk(e); throw logAndReturn( "TM error tx rollback commit", Exceptions.withCause( new SystemException("TM encountered a problem, " + " error writing transaction log"), e)); } tx.setStatus(Status.STATUS_NO_TRANSACTION); RollbackException rollbackException = new RollbackException("Failed to commit, transaction rolledback"); ExceptionCauseSetter.setCause(rollbackException, tx.getRollbackCause()); throw rollbackException; }
// called when a resource gets enlisted void writeStartRecord(byte globalId[]) throws SystemException { try { getTxLog().txStart(globalId); } catch (IOException e) { log.log(Level.SEVERE, "Error writing transaction log", e); setTmNotOk(e); throw logAndReturn( "TM error write start record", Exceptions.withCause( new SystemException("TM encountered a problem, " + " error writing transaction log,"), e)); } }
public synchronized boolean enlistResource(XAResource xaRes) throws RollbackException, IllegalStateException, SystemException { if (xaRes == null) { throw new IllegalArgumentException("Null xa resource"); } if (status == Status.STATUS_ACTIVE || status == Status.STATUS_PREPARING) { try { if (resourceList.size() == 0) { if (!globalStartRecordWritten) { txManager.writeStartRecord(globalId); globalStartRecordWritten = true; } // byte branchId[] = txManager.getBranchId(xaRes); Xid xid = new XidImpl(globalId, branchId); resourceList.add(new ResourceElement(xid, xaRes)); xaRes.start(xid, XAResource.TMNOFLAGS); try { txManager.getTxLog().addBranch(globalId, branchId); } catch (IOException e) { log.log(Level.SEVERE, "Error writing transaction log", e); txManager.setTmNotOk(); throw Exceptions.withCause( new SystemException( "TM encountered a problem, " + " error writing transaction log"), e); } return true; } Xid sameRmXid = null; Iterator<ResourceElement> itr = resourceList.iterator(); while (itr.hasNext()) { ResourceElement re = itr.next(); if (sameRmXid == null && re.getResource().isSameRM(xaRes)) { sameRmXid = re.getXid(); } if (xaRes == re.getResource()) { if (re.getStatus() == RS_SUSPENDED) { xaRes.start(re.getXid(), XAResource.TMRESUME); } else { // either enlisted or delisted // is TMJOIN correct then? xaRes.start(re.getXid(), XAResource.TMJOIN); } re.setStatus(RS_ENLISTED); return true; } } if (sameRmXid != null) // should we join? { addResourceToList(sameRmXid, xaRes); xaRes.start(sameRmXid, XAResource.TMJOIN); } else // new branch { // ResourceElement re = resourceList.getFirst(); byte branchId[] = txManager.getBranchId(xaRes); Xid xid = new XidImpl(globalId, branchId); addResourceToList(xid, xaRes); xaRes.start(xid, XAResource.TMNOFLAGS); try { txManager.getTxLog().addBranch(globalId, branchId); } catch (IOException e) { log.log(Level.SEVERE, "Error writing transaction log", e); txManager.setTmNotOk(); throw Exceptions.withCause( new SystemException( "TM encountered a problem, " + " error writing transaction log"), e); } } return true; } catch (XAException e) { log.log(Level.SEVERE, "Unable to enlist resource[" + xaRes + "]", e); status = Status.STATUS_MARKED_ROLLBACK; return false; } } else if (status == Status.STATUS_ROLLING_BACK || status == Status.STATUS_ROLLEDBACK || status == Status.STATUS_MARKED_ROLLBACK) { throw new RollbackException("Tx status is: " + txManager.getTxStatusAsString(status)); } throw new IllegalStateException("Tx status is: " + txManager.getTxStatusAsString(status)); }
public void rollback() throws IllegalStateException, SystemException { assertTmOk("tx rollback"); Thread thread = Thread.currentThread(); TransactionImpl tx = txThreadMap.get(thread); if (tx == null) { throw new IllegalStateException("Not in transaction"); } boolean hasAnyLocks = false; try { hasAnyLocks = finishHook.hasAnyLocks(tx); if (tx.getStatus() == Status.STATUS_ACTIVE || tx.getStatus() == Status.STATUS_MARKED_ROLLBACK || tx.getStatus() == Status.STATUS_PREPARING) { tx.setStatus(Status.STATUS_MARKED_ROLLBACK); tx.doBeforeCompletion(); // delist resources? try { rolledBackTxCount.incrementAndGet(); tx.doRollback(); } catch (XAException e) { log.log( Level.SEVERE, "Unable to rollback marked or active transaction. " + "Some resources may be commited others not. " + "Neo4j kernel should be SHUTDOWN for " + "resource maintance and transaction recovery ---->", e); setTmNotOk(e); throw logAndReturn( "TM error tx rollback", Exceptions.withCause( new SystemException( "Unable to rollback " + " ---> error code for rollback: " + e.errorCode), e)); } tx.doAfterCompletion(); txThreadMap.remove(thread); try { if (tx.isGlobalStartRecordWritten()) { getTxLog().txDone(tx.getGlobalId()); } } catch (IOException e) { log.log(Level.SEVERE, "Error writing transaction log", e); setTmNotOk(e); throw logAndReturn( "TM error tx rollback", Exceptions.withCause( new SystemException( "TM encountered a problem, " + " error writing transaction log"), e)); } tx.setStatus(Status.STATUS_NO_TRANSACTION); } else { throw new IllegalStateException("Tx status is: " + getTxStatusAsString(tx.getStatus())); } } finally { if (hasAnyLocks) { finishHook.finishTransaction(tx.getEventIdentifier(), false); } } }
private void commit(Thread thread, TransactionImpl tx) throws SystemException, HeuristicMixedException, HeuristicRollbackException { // mark as commit in log done TxImpl.doCommit() Throwable commitFailureCause = null; int xaErrorCode = -1; if (tx.getResourceCount() == 0) { tx.setStatus(Status.STATUS_COMMITTED); } else { try { tx.doCommit(); } catch (XAException e) { xaErrorCode = e.errorCode; log.log( Level.SEVERE, "Commit failed, status=" + getTxStatusAsString(tx.getStatus()) + ", errorCode=" + xaErrorCode, e); if (tx.getStatus() == Status.STATUS_COMMITTED) { // this should never be setTmNotOk(e); throw logAndReturn( "TM error tx commit", new TransactionFailureException( "commit threw exception but status is committed?", e)); } } catch (Throwable t) { log.log(Level.SEVERE, "Commit failed", t); commitFailureCause = t; } } if (tx.getStatus() != Status.STATUS_COMMITTED) { try { tx.doRollback(); } catch (Throwable e) { log.log( Level.SEVERE, "Unable to rollback transaction. " + "Some resources may be commited others not. " + "Neo4j kernel should be SHUTDOWN for " + "resource maintance and transaction recovery ---->", e); setTmNotOk(e); String commitError; if (commitFailureCause != null) { commitError = "error in commit: " + commitFailureCause; } else { commitError = "error code in commit: " + xaErrorCode; } String rollbackErrorCode = "Uknown error code"; if (e instanceof XAException) { rollbackErrorCode = Integer.toString(((XAException) e).errorCode); } throw logAndReturn( "TM error tx commit", Exceptions.withCause( new HeuristicMixedException( "Unable to rollback ---> " + commitError + " ---> error code for rollback: " + rollbackErrorCode), e)); } tx.doAfterCompletion(); txThreadMap.remove(thread); try { if (tx.isGlobalStartRecordWritten()) { getTxLog().txDone(tx.getGlobalId()); } } catch (IOException e) { log.log(Level.SEVERE, "Error writing transaction log", e); setTmNotOk(e); throw logAndReturn( "TM error tx commit", Exceptions.withCause( new SystemException( "TM encountered a problem, " + " error writing transaction log"), e)); } tx.setStatus(Status.STATUS_NO_TRANSACTION); if (commitFailureCause == null) { throw logAndReturn( "TM error tx commit", new HeuristicRollbackException( "Failed to commit, transaction rolledback ---> " + "error code was: " + xaErrorCode)); } else { throw logAndReturn( "TM error tx commit", Exceptions.withCause( new HeuristicRollbackException( "Failed to commit, transaction rolledback ---> " + commitFailureCause), commitFailureCause)); } } tx.doAfterCompletion(); txThreadMap.remove(thread); try { if (tx.isGlobalStartRecordWritten()) { getTxLog().txDone(tx.getGlobalId()); } } catch (IOException e) { log.log(Level.SEVERE, "Error writing transaction log", e); setTmNotOk(e); throw logAndReturn( "TM error tx commit", Exceptions.withCause( new SystemException("TM encountered a problem, " + " error writing transaction log"), e)); } tx.setStatus(Status.STATUS_NO_TRANSACTION); }