use of com.orientechnologies.orient.core.storage.impl.local.paginated.wal.ONonTxOperationPerformedWALRecord 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;
}
Aggregations