core/src/main/java/com/orientechnologies/orient/core/storage/impl/local/paginated/atomicoperations/OAtomicOperationsManager.java
public OAtomicOperation startAtomicOperation(String lockName, boolean trackNonTxOperations) throws IOException {
    OAtomicOperation operation = currentOperation.get();
    if (operation != null) {
      operation.incrementCounter();

      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());
    currentOperation.set(operation);

    if (trackAtomicOperations) {
      final Thread thread = Thread.currentThread();
      activeAtomicOperations.put(unitId, new OPair<>(thread.getName(), thread.getStackTrace()));
    }

    if (useWal && trackNonTxOperations && storage.getStorageTransaction() == null) {
      writeAheadLog.log(new ONonTxOperationPerformedWALRecord());
    }

    if (lockName != null) {
      acquireExclusiveLockTillOperationComplete(operation, lockName);
    }

    try {
      storage.checkReadOnlyConditions();
    } catch (RuntimeException | Error e) {
      final Iterator<String> lockedObjectIterator = operation.lockedObjects().iterator();

      while (lockedObjectIterator.hasNext()) {
        final String lockedObject = lockedObjectIterator.next();
        lockedObjectIterator.remove();

        lockManager.releaseLock(this, lockedObject, OOneEntryPerKeyLockManager.LOCK.EXCLUSIVE);
      }

      throw e;
    }

    return operation;
  }
public OAtomicOperation startAtomicOperation(String lockName, boolean trackNonTxOperations) throws IOException {
    OAtomicOperation operation = currentOperation.get();
    if (operation != null) {
      operation.incrementCounter();

      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());
    currentOperation.set(operation);

    if (trackAtomicOperations) {
      final Thread thread = Thread.currentThread();
      activeAtomicOperations.put(unitId, new OPair<>(thread.getName(), thread.getStackTrace()));
    }

    if (useWal && trackNonTxOperations && storage.getStorageTransaction() == null) {
      writeAheadLog.log(new ONonTxOperationPerformedWALRecord());
    }

    if (lockName != null) {
      acquireExclusiveLockTillOperationComplete(operation, lockName);
    }

    try {
      storage.checkReadOnlyConditions();
    } catch (RuntimeException | Error e) {
      final Iterator<String> lockedObjectIterator = operation.lockedObjects().iterator();

      while (lockedObjectIterator.hasNext()) {
        final String lockedObject = lockedObjectIterator.next();
        lockedObjectIterator.remove();

        lockManager.releaseLock(this, lockedObject, OOneEntryPerKeyLockManager.LOCK.EXCLUSIVE);
      }

      throw e;
    }

    return operation;
  }
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>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 rolled back).
<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>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.