Search in sources :

Example 1 with OOperationUnitId

use of com.orientechnologies.orient.core.storage.impl.local.paginated.wal.OOperationUnitId in project orientdb by orientechnologies.

the class OAtomicOperationsManager method startAtomicOperation.

/**
   * Starts atomic operation inside of current thread. If atomic operation has been already started, current atomic operation
   * instance will be returned. All durable components have to call this method at the beginning of any data modification
   * operation.
   * <p>
   * <p>In current implementation of atomic operation, each component which is participated in atomic operation is hold under
   * exclusive lock till atomic operation will not be completed (committed or rollbacked).
   * <p>
   * <p>If other thread is going to read data from component it has to acquire read lock inside of atomic operation manager {@link
   * #acquireReadLock(ODurableComponent)}, otherwise data consistency will be compromised.
   * <p>
   * <p>Atomic operation may be delayed if start of atomic operations is prohibited by call of {@link
   * #freezeAtomicOperations(Class, String)} method. If mentioned above method is called then execution of current method will be
   * stopped till call of {@link #releaseAtomicOperations(long)} method or exception will be thrown. Concrete behaviour depends on
   * real values of parameters of {@link #freezeAtomicOperations(Class, String)} method.
   *
   * @param trackNonTxOperations If this flag set to <code>true</code> then special record {@link ONonTxOperationPerformedWALRecord}
   *                             will be added to WAL in case of atomic operation is started outside of active storage transaction.
   *                             During storage restore procedure this record is monitored and if given record is present then
   *                             rebuild of all indexes is performed.
   * @param lockName             Name of lock (usually name of component) which is going participate in atomic operation.
   *
   * @return Instance of active atomic operation.
   */
public OAtomicOperation startAtomicOperation(String lockName, boolean trackNonTxOperations) throws IOException {
    OAtomicOperation operation = currentOperation.get();
    if (operation != null) {
        operation.incrementCounter();
        if (trackAtomicOperations) {
            final OPair<String, Deque<OPair<String, StackTraceElement[]>>> atomicPair = activeAtomicOperations.get(operation.getOperationUnitId());
            if (atomicPair == null) {
                throw new IllegalStateException("Atomic operation is not registered in manager");
            }
            final Deque<OPair<String, StackTraceElement[]>> stack = atomicPair.getValue();
            stack.push(new OPair<String, StackTraceElement[]>(lockName, Thread.currentThread().getStackTrace()));
        }
        if (lockName != null)
            acquireExclusiveLockTillOperationComplete(operation, lockName);
        return operation;
    }
    atomicOperationsCount.increment();
    while (freezeRequests.get() > 0) {
        assert freezeRequests.get() >= 0;
        atomicOperationsCount.decrement();
        throwFreezeExceptionIfNeeded();
        final Thread thread = Thread.currentThread();
        addThreadInWaitingList(thread);
        if (freezeRequests.get() > 0) {
            LockSupport.park(this);
        }
        atomicOperationsCount.increment();
    }
    assert freezeRequests.get() >= 0;
    final boolean useWal = useWal();
    final OOperationUnitId unitId = OOperationUnitId.generateId();
    final OLogSequenceNumber lsn = useWal ? writeAheadLog.logAtomicOperationStartRecord(true, unitId) : null;
    operation = new OAtomicOperation(lsn, unitId, readCache, writeCache, storage.getId(), performanceStatisticManager);
    currentOperation.set(operation);
    if (trackAtomicOperations) {
        final Thread thread = Thread.currentThread();
        final Deque<OPair<String, StackTraceElement[]>> lockStack = new LinkedList<OPair<String, StackTraceElement[]>>();
        final OPair<String, StackTraceElement[]> lockPair = new OPair<String, StackTraceElement[]>(lockName, thread.getStackTrace());
        lockStack.push(lockPair);
        activeAtomicOperations.put(unitId, new OPair<String, Deque<OPair<String, StackTraceElement[]>>>(thread.getName(), lockStack));
    }
    if (useWal && trackNonTxOperations && storage.getStorageTransaction() == null)
        writeAheadLog.log(new ONonTxOperationPerformedWALRecord());
    if (lockName != null)
        acquireExclusiveLockTillOperationComplete(operation, lockName);
    return operation;
}
Also used : Deque(java.util.Deque) ONonTxOperationPerformedWALRecord(com.orientechnologies.orient.core.storage.impl.local.paginated.wal.ONonTxOperationPerformedWALRecord) LinkedList(java.util.LinkedList) OLogSequenceNumber(com.orientechnologies.orient.core.storage.impl.local.paginated.wal.OLogSequenceNumber) OPair(com.orientechnologies.common.util.OPair) OOperationUnitId(com.orientechnologies.orient.core.storage.impl.local.paginated.wal.OOperationUnitId)

Example 2 with OOperationUnitId

use of com.orientechnologies.orient.core.storage.impl.local.paginated.wal.OOperationUnitId in project orientdb by orientechnologies.

the class OAtomicOperationsManager method dumpActiveAtomicOperations.

@Override
public String dumpActiveAtomicOperations() {
    if (!trackAtomicOperations)
        activeAtomicOperations.clear();
    final StringWriter writer = new StringWriter();
    writer.append("List of active atomic operations: \r\n");
    writer.append("------------------------------------------------------------------------------------------------\r\n");
    for (Map.Entry<OOperationUnitId, OPair<String, Deque<OPair<String, StackTraceElement[]>>>> entry : activeAtomicOperations.entrySet()) {
        writer.append("Operation unit id :").append(entry.getKey().toString()).append("\r\n");
        writer.append("Started at thread : ").append(entry.getValue().getKey()).append("\r\n");
        writer.append("Stack trace of methods which participated in this operation : \r\n");
        for (OPair<String, StackTraceElement[]> pair : entry.getValue().getValue()) {
            writer.append("------------------------------------------------------------------------------------------------\r\n");
            writer.append("Lock name :").append(pair.getKey()).append("\r\n");
            StackTraceElement[] stackTraceElements = pair.getValue();
            for (int i = 1; i < stackTraceElements.length; i++) {
                writer.append("\tat ").append(stackTraceElements[i].toString()).append("\r\n");
            }
        }
        writer.append("------------------------------------------------------------------------------------------------\r\n");
        writer.append("\r\n\r\n\r\n\r\n\r\n\r\n");
    }
    writer.append("-------------------------------------------------------------------------------------------------\r\n");
    return writer.toString();
}
Also used : StringWriter(java.io.StringWriter) OPair(com.orientechnologies.common.util.OPair) HashMap(java.util.HashMap) ConcurrentMap(java.util.concurrent.ConcurrentMap) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) OOperationUnitId(com.orientechnologies.orient.core.storage.impl.local.paginated.wal.OOperationUnitId)

Aggregations

OPair (com.orientechnologies.common.util.OPair)2 OOperationUnitId (com.orientechnologies.orient.core.storage.impl.local.paginated.wal.OOperationUnitId)2 OLogSequenceNumber (com.orientechnologies.orient.core.storage.impl.local.paginated.wal.OLogSequenceNumber)1 ONonTxOperationPerformedWALRecord (com.orientechnologies.orient.core.storage.impl.local.paginated.wal.ONonTxOperationPerformedWALRecord)1 StringWriter (java.io.StringWriter)1 Deque (java.util.Deque)1 HashMap (java.util.HashMap)1 LinkedList (java.util.LinkedList)1 Map (java.util.Map)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 ConcurrentMap (java.util.concurrent.ConcurrentMap)1