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;
}
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();
}
Aggregations