Package com.thinkaurelius.titan.diskstorage.persistit

Source Code of com.thinkaurelius.titan.diskstorage.persistit.PersistitTransaction

package com.thinkaurelius.titan.diskstorage.persistit;

import static com.thinkaurelius.titan.diskstorage.persistit.PersistitStoreManager.VOLUME_NAME;

import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Preconditions;
import com.persistit.Exchange;
import com.persistit.Persistit;
import com.persistit.SessionId;
import com.persistit.Transaction;
import com.persistit.exception.PersistitException;
import com.persistit.exception.RollbackException;
import com.thinkaurelius.titan.diskstorage.PermanentStorageException;
import com.thinkaurelius.titan.diskstorage.StorageException;
import com.thinkaurelius.titan.diskstorage.common.AbstractStoreTransaction;
import com.thinkaurelius.titan.diskstorage.keycolumnvalue.StoreTxConfig;

/**
* @todo: read this and make sure multiple threads aren't sharing transactions http://akiban.github.com/persistit/javadoc/com/persistit/Transaction.html#_threadManagement
* @todo: add finalize method
*/
public class PersistitTransaction extends AbstractStoreTransaction {

    private Persistit db;
    private SessionId sessionId;
   
    private static final Logger log = LoggerFactory.getLogger(PersistitTransaction.class);

    private static Queue<SessionId> sessionPool = new ConcurrentLinkedQueue<SessionId>();

    private static SessionId getSessionId() {
        SessionId s = sessionPool.poll();
        if (s == null) {
            s = new SessionId();
        }
        return s;
    }

    private static void returnSessionId(SessionId s) {
        sessionPool.offer(s);
    }

    public PersistitTransaction(Persistit p, StoreTxConfig config) throws StorageException {
        super(config);
        db = p;
        synchronized (this) {
            sessionId = getSessionId();
        }
        assign();
        Preconditions.checkNotNull(sessionId);
        Transaction tx = db.getTransaction();
        assert sessionId == tx.getSessionId();

        try {
            tx.begin();
        } catch (PersistitException ex) {
            throw new PermanentStorageException(ex);
        }
    }

    /**
     * Assigns the session id to the current thread
     */
    public void assign() {
        synchronized (this) {
            Preconditions.checkNotNull(sessionId);
            db.setSessionId(sessionId);
        }
    }

    private void close() {
        returnSessionId(sessionId);
        sessionId = null;
    }

    @Override
    public void rollback() throws StorageException {
        super.rollback();
        synchronized (this) {
            assign();
            Transaction tx = db.getTransaction();
            if (tx.isActive() && !tx.isCommitted()) {
                tx.rollback();
            }
            tx.end();
            close();
        }
    }

    @Override
    public void commit() throws StorageException {
        synchronized (this) {
            if (null == sessionId) { // Already closed
                log.warn("Can't commit {}: already closed, trace to redundant commit follows", this, new IllegalStateException("redundant commit"));
                return;
            }
            super.commit();
            assign();
            Transaction tx = db.getTransaction();
            int retries = 3;
            try {
                if (tx.isActive() && !tx.isRollbackPending()) {
                    int i = 0;
                    while (true) {
                        try {
                            tx.commit(Transaction.CommitPolicy.HARD);
                            tx.end();
                            break;
                        } catch (RollbackException ex) {
                            if (i++ >= retries) {
                                throw ex;
                            }
                        }
                    }
                    close();
                }
            } catch (PersistitException ex) {
                throw new PermanentStorageException(ex);
            }
        }
    }

    public Exchange getExchange(String treeName) throws StorageException {
        return getExchange(treeName, true);
    }

    public Exchange getExchange(String treeName, Boolean create) throws StorageException {
        synchronized (this) {
            Exchange exchange;
            try {
                assign();
                exchange = db.getExchange(VOLUME_NAME, treeName, create);
                return exchange;
            } catch (PersistitException ex) {
                throw new PermanentStorageException(ex);
            }
        }
    }

    public void releaseExchange(Exchange exchange) {
        //
    }
}
TOP

Related Classes of com.thinkaurelius.titan.diskstorage.persistit.PersistitTransaction

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.