public CombinedLocksCondition(LockService lockService, Iterable<HeldLocksToken> externalLockTokens, HeldLocksToken transactionLockToken) { this.externalLocksCondition = new ExternalLocksCondition(lockService, ImmutableSet.copyOf(externalLockTokens)); this.transactionLocksCondition = new TransactionLocksCondition(lockService, transactionLockToken); }
@Override public void cleanup() { // Both of these conditions don't throw internally externalLocksCondition.cleanup(); transactionLocksCondition.cleanup(); }
@Override public Iterable<HeldLocksToken> getLocks() { return Iterables.concat(externalLocksCondition.getLocks(), transactionLocksCondition.getLocks()); } }
@Override public void throwIfConditionInvalid(long timestamp) { externalLocksCondition.throwIfConditionInvalid(timestamp); transactionLocksCondition.throwIfConditionInvalid(timestamp); }
@Test public void externalLocksCondition_conditionSucceeds() { when(lockService.refreshLockRefreshTokens(ImmutableSet.of(EXTERNAL_LOCK_REFRESH_TOKEN))) .thenReturn(ImmutableSet.of(EXTERNAL_LOCK_REFRESH_TOKEN)); externalLocksCondition.throwIfConditionInvalid(0L); }
public static Supplier<AdvisoryLocksCondition> get(LockService lockService, Iterable<HeldLocksToken> lockTokens, Supplier<LockRequest> lockSupplier) { return () -> { Set<HeldLocksToken> externalLocks = ImmutableSet.copyOf(lockTokens); ExternalLocksCondition externalCondition = externalLocks.isEmpty() ? null : new ExternalLocksCondition(lockService, externalLocks); LockRequest lockRequest = lockSupplier.get(); if (lockRequest != null) { Validate.isTrue(lockRequest.getVersionId() == null, "Using a version id is not allowed"); HeldLocksToken newToken = acquireLock(lockService, lockRequest); TransactionLocksCondition transactionCondition = new TransactionLocksCondition(lockService, newToken); return externalCondition == null ? transactionCondition : new CombinedLocksCondition(externalCondition, transactionCondition); } return externalCondition == null ? NO_LOCKS_CONDITION : externalCondition; }; }
@Test public void externalLocksCondition_conditionFails() { when(lockService.refreshLockRefreshTokens(Collections.singleton(EXTERNAL_LOCK_REFRESH_TOKEN))) .thenReturn(ImmutableSet.of()); assertThatThrownBy(() -> externalLocksCondition.throwIfConditionInvalid(0L)) .isInstanceOf(TransactionLockTimeoutNonRetriableException.class) .hasMessageContaining("Provided external lock tokens expired. Retry is not possible"); }
@Test public void externalLocksCondition_cleanUpDoesNotReleaseLock() { externalLocksCondition.cleanup(); verifyZeroInteractions(lockService); }
@Test public void externalLocksCondition_getLocks() { assertThat(externalLocksCondition.getLocks()).containsOnly(EXTERNAL_LOCK_TOKEN); }
@Override public <T, E extends Exception> T runTaskWithLocksThrowOnConflict( Iterable<HeldLocksToken> lockTokens, LockAwareTransactionTask<T, E> task) throws E, TransactionFailedRetriableException { checkOpen(); AdvisoryLocksCondition lockCondition = new ExternalLocksCondition(getLockService(), ImmutableSet.copyOf(lockTokens)); return runTaskWithConditionThrowOnConflict(lockCondition, (transaction, condition) -> task.execute(transaction, condition.getLocks())); } }
@Override public void throwIfConditionInvalid(long timestamp) { externalLocksCondition.throwIfConditionInvalid(timestamp); transactionLocksCondition.throwIfConditionInvalid(timestamp); }
@Override public void cleanup() { // Both of these conditions don't throw internally externalLocksCondition.cleanup(); transactionLocksCondition.cleanup(); }
@Override public Iterable<HeldLocksToken> getLocks() { return Iterables.concat(externalLocksCondition.getLocks(), transactionLocksCondition.getLocks()); } }
@Before public void before() { lockService = mock(LockService.class); transactionLocksCondition = new TransactionLocksCondition(lockService, TRANSACTION_LOCK_TOKEN); externalLocksCondition = new ExternalLocksCondition(lockService, ImmutableSet.of(EXTERNAL_LOCK_TOKEN)); combinedLocksCondition = new CombinedLocksCondition(lockService, ImmutableSet.of(EXTERNAL_LOCK_TOKEN), TRANSACTION_LOCK_TOKEN); }
public CombinedLocksCondition(LockService lockService, Iterable<HeldLocksToken> externalLockTokens, HeldLocksToken transactionLockToken) { this.externalLocksCondition = new ExternalLocksCondition(lockService, ImmutableSet.copyOf(externalLockTokens)); this.transactionLocksCondition = new TransactionLocksCondition(lockService, transactionLockToken); }
public static Supplier<AdvisoryLocksCondition> get(LockService lockService, Iterable<HeldLocksToken> lockTokens, Supplier<LockRequest> lockSupplier) { return () -> { Set<HeldLocksToken> externalLocks = ImmutableSet.copyOf(lockTokens); ExternalLocksCondition externalCondition = externalLocks.isEmpty() ? null : new ExternalLocksCondition(lockService, externalLocks); LockRequest lockRequest = lockSupplier.get(); if (lockRequest != null) { Validate.isTrue(lockRequest.getVersionId() == null, "Using a version id is not allowed"); HeldLocksToken newToken = acquireLock(lockService, lockRequest); TransactionLocksCondition transactionCondition = new TransactionLocksCondition(lockService, newToken); return externalCondition == null ? transactionCondition : new CombinedLocksCondition(externalCondition, transactionCondition); } return externalCondition == null ? NO_LOCKS_CONDITION : externalCondition; }; }
@Override public <T, E extends Exception> T runTaskWithLocksThrowOnConflict( Iterable<HeldLocksToken> lockTokens, LockAwareTransactionTask<T, E> task) throws E, TransactionFailedRetriableException { checkOpen(); AdvisoryLocksCondition lockCondition = new ExternalLocksCondition(getLockService(), ImmutableSet.copyOf(lockTokens)); return runTaskWithConditionThrowOnConflict(lockCondition, (transaction, condition) -> task.execute(transaction, condition.getLocks())); } }