use of org.neo4j.lock.ActiveLock in project neo4j by neo4j.
the class TransactionDependenciesResolverTest method blockingChainDescriptionForDirectlyBlockedTransaction.
@Test
void blockingChainDescriptionForDirectlyBlockedTransaction() {
HashMap<KernelTransactionHandle, Optional<QuerySnapshot>> map = new HashMap<>();
TestKernelTransactionHandle handle1 = new TestKernelTransactionHandleWithLocks(new StubKernelTransaction(), 3, singletonList(new ActiveLock(ResourceTypes.NODE, EXCLUSIVE, 1, 1)));
TestKernelTransactionHandle handle2 = new TestKernelTransactionHandleWithLocks(new StubKernelTransaction());
map.put(handle1, Optional.of(createQuerySnapshot(1)));
map.put(handle2, Optional.of(createQuerySnapshotWaitingForLock(2, SHARED, ResourceTypes.NODE, 1, 1)));
TransactionDependenciesResolver resolver = new TransactionDependenciesResolver(map);
assertThat(resolver.describeBlockingTransactions(handle1)).isEmpty();
assertEquals("[transaction-3]", resolver.describeBlockingTransactions(handle2));
}
use of org.neo4j.lock.ActiveLock in project neo4j by neo4j.
the class TransactionDependenciesResolverTest method detectBlockedTransactionsByExclusiveLock.
@Test
void detectBlockedTransactionsByExclusiveLock() {
HashMap<KernelTransactionHandle, Optional<QuerySnapshot>> map = new HashMap<>();
TestKernelTransactionHandle handle1 = new TestKernelTransactionHandleWithLocks(new StubKernelTransaction(), 0, singletonList(new ActiveLock(ResourceTypes.NODE, EXCLUSIVE, 1, 1)));
TestKernelTransactionHandle handle2 = new TestKernelTransactionHandleWithLocks(new StubKernelTransaction());
map.put(handle1, Optional.of(createQuerySnapshot(1)));
map.put(handle2, Optional.of(createQuerySnapshotWaitingForLock(2, SHARED, ResourceTypes.NODE, 1, 1)));
TransactionDependenciesResolver resolver = new TransactionDependenciesResolver(map);
assertFalse(resolver.isBlocked(handle1));
assertTrue(resolver.isBlocked(handle2));
}
use of org.neo4j.lock.ActiveLock in project neo4j by neo4j.
the class RelationshipLockHelperTest method avoidTakingDuplicateLocks.
@Test
void avoidTakingDuplicateLocks() {
MutableLongObjectMap<RecordAccess.RecordProxy<RelationshipRecord, Void>> proxies = LongObjectMaps.mutable.empty();
MutableLongSet idsToDelete = LongSets.mutable.empty();
MutableLongBag expectedLocks = LongBags.mutable.empty();
idsToDelete.add(1);
RelationshipRecord record = new RelationshipRecord(1);
record.initialize(true, 1, 2, 3, 4, 5, 7, 7, 5, false, false);
var proxy = mock(RecordAccess.RecordProxy.class);
when(proxy.forReadingLinkage()).thenAnswer(invocation -> record);
proxies.put(1, proxy);
RecordAccess<RelationshipRecord, Void> relRecords = mock(RecordAccess.class);
when(relRecords.getOrLoad(Mockito.anyLong(), Mockito.any(), Mockito.any())).thenAnswer(invocation -> proxies.get(invocation.getArgument(0)));
TrackingResourceLocker locks = new TrackingResourceLocker(random, NO_MONITOR).withStrictAssertionsOn(ResourceTypes.RELATIONSHIP);
RelationshipLockHelper.lockRelationshipsInOrder(idsAsBatch(idsToDelete), 2, relRecords, locks, CursorContext.NULL, EmptyMemoryTracker.INSTANCE);
List<ActiveLock> activeLocks = locks.activeLocks().collect(Collectors.toList());
assertThat(activeLocks).hasSize(4).contains(new ActiveLock(ResourceTypes.RELATIONSHIP, LockType.EXCLUSIVE, -1, 1)).contains(new ActiveLock(ResourceTypes.RELATIONSHIP, LockType.EXCLUSIVE, -1, 2)).contains(new ActiveLock(ResourceTypes.RELATIONSHIP, LockType.EXCLUSIVE, -1, 5)).contains(new ActiveLock(ResourceTypes.RELATIONSHIP, LockType.EXCLUSIVE, -1, 7));
}
use of org.neo4j.lock.ActiveLock in project neo4j by neo4j.
the class ForsetiClient method collectActiveLocks.
private static void collectActiveLocks(LongIntMap[] counts, List<ActiveLock> locks, LockType lockType, long userTransactionId) {
for (int typeId = 0; typeId < counts.length; typeId++) {
LongIntMap lockCounts = counts[typeId];
if (lockCounts != null) {
ResourceType resourceType = ResourceTypes.fromId(typeId);
lockCounts.forEachKeyValue((resourceId, count) -> locks.add(new ActiveLock(resourceType, lockType, userTransactionId, resourceId)));
}
}
}
use of org.neo4j.lock.ActiveLock in project neo4j by neo4j.
the class ExecutingQuery method snapshot.
// snapshot state
public QuerySnapshot snapshot() {
// capture a consistent snapshot of the "live" state
ExecutingQueryStatus status;
long waitTimeNanos;
long currentTimeNanos;
long cpuTimeNanos;
String queryText;
MapValue queryParameters;
do {
// read barrier, must be first
status = this.status;
// the reason for the retry loop: don't count the wait time twice
waitTimeNanos = this.waitTimeNanos;
cpuTimeNanos = cpuClock.cpuTimeNanos(threadExecutingTheQueryId);
// capture the time as close to the snapshot as possible
currentTimeNanos = clock.nanos();
queryText = this.obfuscatedQueryText;
queryParameters = this.obfuscatedQueryParameters;
} while (this.status != status);
// guarded by barrier - unused if status is planning, stable otherwise
long compilationCompletedNanos = this.compilationCompletedNanos;
// guarded by barrier - like compilationCompletedNanos
CompilerInfo planner = status.isParsingOrPlanning() ? null : this.compilerInfo;
List<ActiveLock> waitingOnLocks = status.isWaitingOnLocks() ? status.waitingOnLocks() : Collections.emptyList();
// activeLockCount is not atomic to capture, so we capture it after the most sensitive part.
long totalActiveLocks = transactionBinding.activeLockCount.getAsLong();
// just needs to be captured at some point...
var hits = pageHitsOfClosedTransactions + transactionBinding.hitsSupplier.getAsLong();
var faults = pageFaultsOfClosedTransactions + transactionBinding.faultsSupplier.getAsLong();
PageCounterValues pageCounters = new PageCounterValues(hits, faults);
// - at this point we are done capturing the "live" state, and can start computing the snapshot -
long compilationTimeNanos = (status.isParsingOrPlanning() ? currentTimeNanos : compilationCompletedNanos) - startTimeNanos;
long elapsedTimeNanos = currentTimeNanos - startTimeNanos;
cpuTimeNanos -= cpuTimeNanosWhenQueryStarted;
waitTimeNanos += status.waitTimeNanos(currentTimeNanos);
return new QuerySnapshot(this, planner, pageCounters, NANOSECONDS.toMicros(compilationTimeNanos), NANOSECONDS.toMicros(elapsedTimeNanos), cpuTimeNanos == 0 && cpuTimeNanosWhenQueryStarted == -1 ? -1 : NANOSECONDS.toMicros(cpuTimeNanos), NANOSECONDS.toMicros(waitTimeNanos), status.name(), status.toMap(currentTimeNanos), waitingOnLocks, totalActiveLocks - transactionBinding.initialActiveLocks, memoryTracker.totalAllocatedMemory(), Optional.ofNullable(queryText), Optional.ofNullable(queryParameters), transactionId);
}
Aggregations