use of javax.transaction.xa.Xid in project graphdb by neo4j-attic.
the class ReadOnlyTransactionImpl method isOnePhase.
private boolean isOnePhase() {
if (resourceList.size() == 0) {
log.severe("Detected zero resources in resourceList");
return true;
}
// check for more than one unique xid
Iterator<ResourceElement> itr = resourceList.iterator();
Xid xid = itr.next().getXid();
while (itr.hasNext()) {
if (!xid.equals(itr.next().getXid())) {
return false;
}
}
return true;
}
use of javax.transaction.xa.Xid in project neo4j-mobile-android by neo4j-contrib.
the class TransactionImpl method enlistResource.
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(e);
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 (// should we join?
sameRmXid != null) {
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(e);
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));
}
use of javax.transaction.xa.Xid in project neo4j-mobile-android by neo4j-contrib.
the class TxLog method getDanglingRecords.
/**
* Returns an array of lists, each list contains dangling records
* (transactions that han't been completed yet) grouped after global by
* transaction id.
*/
public synchronized Iterator<List<Record>> getDanglingRecords() throws IOException {
FileChannel fileChannel = logBuffer.getFileChannel();
ByteBuffer buffer = ByteBuffer.allocateDirect((3 + Xid.MAXGTRIDSIZE + Xid.MAXBQUALSIZE) * 1000);
fileChannel.position(0);
buffer.clear();
fileChannel.read(buffer);
buffer.flip();
// next record position
long nextPosition = 0;
// holds possible dangling records
int seqNr = 0;
Map<Xid, List<Record>> recordMap = new HashMap<Xid, List<Record>>();
while (buffer.hasRemaining()) {
byte recordType = buffer.get();
if (recordType == TX_START) {
if (!buffer.hasRemaining()) {
break;
}
byte[] globalId = new byte[buffer.get()];
if (buffer.limit() - buffer.position() < globalId.length) {
break;
}
buffer.get(globalId);
Xid xid = new XidImpl(globalId, new byte[0]);
if (recordMap.containsKey(xid)) {
throw new IOException("Tx start for same xid[" + xid + "] found twice");
}
List<Record> recordList = new LinkedList<Record>();
recordList.add(new Record(recordType, globalId, null, seqNr++));
recordMap.put(xid, recordList);
nextPosition += 2 + globalId.length;
} else if (recordType == BRANCH_ADD) {
if (buffer.limit() - buffer.position() < 2) {
break;
}
byte[] globalId = new byte[buffer.get()];
byte[] branchId = new byte[buffer.get()];
if (buffer.limit() - buffer.position() < globalId.length + branchId.length) {
break;
}
buffer.get(globalId);
buffer.get(branchId);
Xid xid = new XidImpl(globalId, new byte[0]);
if (!recordMap.containsKey(xid)) {
throw new IOException("Branch[" + UTF8.decode(branchId) + "] found for [" + xid + "] but no record list found in map");
}
recordMap.get(xid).add(new Record(recordType, globalId, branchId, seqNr++));
nextPosition += 3 + globalId.length + branchId.length;
} else if (recordType == MARK_COMMIT) {
if (!buffer.hasRemaining()) {
break;
}
byte[] globalId = new byte[buffer.get()];
if (buffer.limit() - buffer.position() < globalId.length) {
break;
}
buffer.get(globalId);
Xid xid = new XidImpl(globalId, new byte[0]);
if (!recordMap.containsKey(xid)) {
throw new IOException("Commiting xid[" + xid + "] mark found but no record list found in map");
}
List<Record> recordList = recordMap.get(xid);
recordList.add(new Record(recordType, globalId, null, seqNr++));
recordMap.put(xid, recordList);
nextPosition += 2 + globalId.length;
} else if (recordType == TX_DONE) {
if (!buffer.hasRemaining()) {
break;
}
byte[] globalId = new byte[buffer.get()];
if (buffer.limit() - buffer.position() < globalId.length) {
break;
}
buffer.get(globalId);
Xid xid = new XidImpl(globalId, new byte[0]);
if (!recordMap.containsKey(xid)) {
throw new IOException("Commiting xid[" + xid + "] mark found but no record list found in map");
}
recordMap.remove(xid);
nextPosition += 2 + globalId.length;
} else if (recordType == 0) {
continue;
} else {
throw new IOException("Unknown type: " + recordType);
}
if ((buffer.limit() - buffer.position()) < (3 + Xid.MAXGTRIDSIZE + Xid.MAXBQUALSIZE)) {
// make sure we don't try to read non full entry
buffer.clear();
fileChannel.position(nextPosition);
fileChannel.read(buffer);
buffer.flip();
}
}
return recordMap.values().iterator();
}
use of javax.transaction.xa.Xid in project neo4j-mobile-android by neo4j-contrib.
the class TxManager method buildRecoveryInfo.
private void buildRecoveryInfo(List<NonCompletedTransaction> commitList, List<Xid> rollbackList, Map<Resource, XAResource> resourceMap, Iterator<List<TxLog.Record>> danglingRecordList) {
while (danglingRecordList.hasNext()) {
Iterator<TxLog.Record> dListItr = danglingRecordList.next().iterator();
TxLog.Record startRecord = dListItr.next();
if (startRecord.getType() != TxLog.TX_START) {
throw logAndReturn("TM error building recovery info", new TransactionFailureException("First record not a start record, type=" + startRecord.getType()));
}
// get branches & commit status
HashSet<Resource> branchSet = new HashSet<Resource>();
int markedCommit = -1;
while (dListItr.hasNext()) {
TxLog.Record record = dListItr.next();
if (record.getType() == TxLog.BRANCH_ADD) {
if (markedCommit != -1) {
throw logAndReturn("TM error building recovery info", new TransactionFailureException("Already marked commit " + startRecord));
}
branchSet.add(new Resource(record.getBranchId()));
} else if (record.getType() == TxLog.MARK_COMMIT) {
if (markedCommit != -1) {
throw logAndReturn("TM error building recovery info", new TransactionFailureException("Already marked commit " + startRecord));
}
markedCommit = record.getSequenceNumber();
} else {
throw logAndReturn("TM error building recovery info", new TransactionFailureException("Illegal record type[" + record.getType() + "]"));
}
}
Iterator<Resource> resourceItr = branchSet.iterator();
List<Xid> xids = new LinkedList<Xid>();
while (resourceItr.hasNext()) {
Resource resource = resourceItr.next();
if (!resourceMap.containsKey(resource)) {
resourceMap.put(resource, getXaResource(resource.getResourceId()));
}
xids.add(new XidImpl(startRecord.getGlobalId(), resource.getResourceId()));
}
if (// this xid needs to be committed
markedCommit != -1) {
commitList.add(new NonCompletedTransaction(markedCommit, xids));
} else {
rollbackList.addAll(xids);
}
}
}
use of javax.transaction.xa.Xid in project neo4j-mobile-android by neo4j-contrib.
the class ReadOnlyTransactionImpl method isOnePhase.
private boolean isOnePhase() {
if (resourceList.size() == 0) {
log.severe("Detected zero resources in resourceList");
return true;
}
// check for more than one unique xid
Iterator<ResourceElement> itr = resourceList.iterator();
Xid xid = itr.next().getXid();
while (itr.hasNext()) {
if (!xid.equals(itr.next().getXid())) {
return false;
}
}
return true;
}
Aggregations