Package com.orientechnologies.orient.core.tx

Source Code of com.orientechnologies.orient.core.tx.OTransactionAbstract

/*
  *
  *  *  Copyright 2014 Orient Technologies LTD (info(at)orientechnologies.com)
  *  *
  *  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  *  you may not use this file except in compliance with the License.
  *  *  You may obtain a copy of the License at
  *  *
  *  *       http://www.apache.org/licenses/LICENSE-2.0
  *  *
  *  *  Unless required by applicable law or agreed to in writing, software
  *  *  distributed under the License is distributed on an "AS IS" BASIS,
  *  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  *  *  See the License for the specific language governing permissions and
  *  *  limitations under the License.
  *  *
  *  * For more information: http://www.orientechnologies.com
  *
  */
package com.orientechnologies.orient.core.tx;

import com.orientechnologies.common.concur.lock.OLockException;
import com.orientechnologies.common.log.OLogManager;
import com.orientechnologies.orient.core.cache.OLocalRecordCache;
import com.orientechnologies.orient.core.db.ODatabaseListener;
import com.orientechnologies.orient.core.db.raw.ODatabaseRaw;
import com.orientechnologies.orient.core.db.record.ODatabaseRecordTx;
import com.orientechnologies.orient.core.db.record.OIdentifiable;
import com.orientechnologies.orient.core.db.record.ORecordOperation;
import com.orientechnologies.orient.core.id.ORID;
import com.orientechnologies.orient.core.storage.OStorage;
import com.orientechnologies.orient.core.storage.OStorageEmbedded;

import java.util.HashMap;
import java.util.Map;

public abstract class OTransactionAbstract implements OTransaction {
  protected final ODatabaseRecordTx                  database;
  protected TXSTATUS                                 status = TXSTATUS.INVALID;
  protected HashMap<ORID, OStorage.LOCKING_STRATEGY> locks  = new HashMap<ORID, OStorage.LOCKING_STRATEGY>();

  protected OTransactionAbstract(final ODatabaseRecordTx iDatabase) {
    database = iDatabase;
  }

  public static void updateCacheFromEntries(final OTransaction tx, final Iterable<? extends ORecordOperation> entries,
      final boolean updateStrategy) {
    final OLocalRecordCache dbCache = tx.getDatabase().getLocalCache();

    for (ORecordOperation txEntry : entries) {
      if (!updateStrategy)
        // ALWAYS REMOVE THE RECORD FROM CACHE
        dbCache.deleteRecord(txEntry.getRecord().getIdentity());
      else if (txEntry.type == ORecordOperation.DELETED)
        // DELETION
        dbCache.deleteRecord(txEntry.getRecord().getIdentity());
      else if (txEntry.type == ORecordOperation.UPDATED || txEntry.type == ORecordOperation.CREATED)
        // UDPATE OR CREATE
        dbCache.updateRecord(txEntry.getRecord());
    }
  }

  public boolean isActive() {
    return status != TXSTATUS.INVALID && status != TXSTATUS.COMPLETED && status != TXSTATUS.ROLLED_BACK;
  }

  public TXSTATUS getStatus() {
    return status;
  }

  public ODatabaseRecordTx getDatabase() {
    return database;
  }

  /**
   * Closes the transaction and releases all the acquired locks.
   */
  @Override
  public void close() {
    for (Map.Entry<ORID, OStorage.LOCKING_STRATEGY> lock : locks.entrySet()) {
      try {
        if (lock.getValue().equals(OStorage.LOCKING_STRATEGY.KEEP_EXCLUSIVE_LOCK))
          ((OStorageEmbedded) getDatabase().getStorage()).releaseWriteLock(lock.getKey());
        else if (lock.getValue().equals(OStorage.LOCKING_STRATEGY.KEEP_SHARED_LOCK))
          ((OStorageEmbedded) getDatabase().getStorage()).releaseReadLock(lock.getKey());
      } catch (Exception e) {
        OLogManager.instance().debug(this, "Error on releasing lock against record " + lock.getKey());
      }
    }
    locks.clear();
  }

  @Override
  public OTransaction lockRecord(final OIdentifiable iRecord, final OStorage.LOCKING_STRATEGY iLockingStrategy) {
    final OStorage stg = database.getStorage();
    if (!(stg.getUnderlying() instanceof OStorageEmbedded))
      throw new OLockException("Cannot lock record across remote connections");

    final ORID rid = iRecord.getIdentity();
    // if (locks.containsKey(rid))
    // throw new IllegalStateException("Record " + rid + " is already locked");

    if (iLockingStrategy == OStorage.LOCKING_STRATEGY.KEEP_EXCLUSIVE_LOCK)
      ((OStorageEmbedded) stg.getUnderlying()).acquireWriteLock(rid);
    else
      ((OStorageEmbedded) stg.getUnderlying()).acquireReadLock(rid);

    locks.put(rid, iLockingStrategy);
    return this;
  }

  @Override
  public OTransaction unlockRecord(final OIdentifiable iRecord) {
    final OStorage stg = database.getStorage();
    if (!(stg.getUnderlying() instanceof OStorageEmbedded))
      throw new OLockException("Cannot lock record across remote connections");

    final ORID rid = iRecord.getIdentity();

    final OStorage.LOCKING_STRATEGY lock = locks.remove(rid);

    if (lock == null)
      throw new OLockException("Cannot unlock a never acquired lock");
    else if (lock == OStorage.LOCKING_STRATEGY.KEEP_EXCLUSIVE_LOCK)
      ((OStorageEmbedded) stg.getUnderlying()).releaseWriteLock(rid);
    else
      ((OStorageEmbedded) stg.getUnderlying()).releaseReadLock(rid);

    return this;
  }

  @Override
  public HashMap<ORID, OStorage.LOCKING_STRATEGY> getLockedRecords() {
    return locks;
  }

  protected void invokeCommitAgainstListeners() {
    // WAKE UP LISTENERS
    for (ODatabaseListener listener : ((ODatabaseRaw) database.getUnderlying()).browseListeners())
      try {
        listener.onBeforeTxCommit(database.getUnderlying());
      } catch (Throwable t) {
        OLogManager.instance().error(this, "Error on commit callback against listener: " + listener, t);
      }
  }

  protected void invokeRollbackAgainstListeners() {
    // WAKE UP LISTENERS
    for (ODatabaseListener listener : ((ODatabaseRaw) database.getUnderlying()).browseListeners())
      try {
        listener.onBeforeTxRollback(database.getUnderlying());
      } catch (Throwable t) {
        OLogManager.instance().error(this, "Error on rollback callback against listener: " + listener, t);
      }
  }
}
TOP

Related Classes of com.orientechnologies.orient.core.tx.OTransactionAbstract

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.