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; }
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)); }