Search in sources :

Example 21 with Xid

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;
}
Also used : Xid(javax.transaction.xa.Xid)

Example 22 with Xid

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));
}
Also used : Xid(javax.transaction.xa.Xid) XAException(javax.transaction.xa.XAException) SystemException(javax.transaction.SystemException) IOException(java.io.IOException) HeuristicRollbackException(javax.transaction.HeuristicRollbackException) RollbackException(javax.transaction.RollbackException)

Example 23 with Xid

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();
}
Also used : HashMap(java.util.HashMap) FileChannel(java.nio.channels.FileChannel) IOException(java.io.IOException) ByteBuffer(java.nio.ByteBuffer) LinkedList(java.util.LinkedList) Xid(javax.transaction.xa.Xid) ArrayList(java.util.ArrayList) List(java.util.List) LinkedList(java.util.LinkedList)

Example 24 with Xid

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);
        }
    }
}
Also used : XAResource(javax.transaction.xa.XAResource) XaResource(org.neo4j.kernel.impl.transaction.xaframework.XaResource) LinkedList(java.util.LinkedList) TransactionFailureException(org.neo4j.graphdb.TransactionFailureException) Xid(javax.transaction.xa.Xid) HashSet(java.util.HashSet)

Example 25 with Xid

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;
}
Also used : Xid(javax.transaction.xa.Xid)

Aggregations

Xid (javax.transaction.xa.Xid)63 Test (org.junit.Test)23 XAException (javax.transaction.xa.XAException)19 IOException (java.io.IOException)16 XAResource (javax.transaction.xa.XAResource)13 XidImpl (org.neo4j.kernel.impl.transaction.XidImpl)11 LinkedList (java.util.LinkedList)10 InOrder (org.mockito.InOrder)6 HashMap (java.util.HashMap)5 RelationshipType (org.neo4j.graphdb.RelationshipType)5 HazelcastXAResource (com.hazelcast.transaction.HazelcastXAResource)4 ArrayList (java.util.ArrayList)4 RollbackException (javax.transaction.RollbackException)4 TransactionFailureException (org.neo4j.graphdb.TransactionFailureException)4 XaResource (org.neo4j.kernel.impl.transaction.xaframework.XaResource)4 TransactionContext (com.hazelcast.transaction.TransactionContext)3 SerializableXID (com.hazelcast.transaction.impl.xa.SerializableXID)3 SystemException (javax.transaction.SystemException)3 HazelcastInstance (com.hazelcast.core.HazelcastInstance)2 HashSet (java.util.HashSet)2