/** * Get the hold timeout configured for this instance. * * <p> * The hold timeout limits how long a thread may hold on to a contested lock before being forced to release * all of its locks; after that, the next attempted operation will fail with {@link RetryTransactionException}. * * @return hold timeout in milliseconds */ public long getHoldTimeout() { return this.lockManager.getHoldTimeout(); }
synchronized void rollback(SimpleKVTransaction tx) { // Prevent use after commit() or rollback() invoked if (tx.stale) return; tx.stale = true; // Release all locks this.lockManager.release(tx.lockOwner); }
/** * Set the hold timeout for this instance. Default is {@link #DEFAULT_HOLD_TIMEOUT}. * * @param holdTimeout how long a thread may hold a contestested lock before throwing {@link RetryTransactionException} * in milliseconds, or zero for unlimited * @throws IllegalArgumentException if {@code holdTimeout} is negative */ public void setHoldTimeout(long holdTimeout) { this.lockManager.setHoldTimeout(holdTimeout); }
if (assertionsEnabled) { for (Mutation mutation : tx.mutations) { if (!this.lockManager.isLocked(tx.lockOwner, mutation.getMin(), mutation.getMax(), true)) { allMutationsWereLocked = false; break; if (!this.lockManager.release(tx.lockOwner)) { throw new TransactionTimeoutException(tx, "transaction taking too long: hold timeout of " + this.lockManager.getHoldTimeout() + "ms has expired");
private void checkUsable(SimpleKVTransaction tx) { if (tx.stale) throw new StaleTransactionException(tx); if (this.lockManager.checkHoldTimeout(tx.lockOwner) == -1) { this.rollback(tx); throw new TransactionTimeoutException(tx, "transaction taking too long: hold timeout of " + this.lockManager.getHoldTimeout() + "ms has expired"); } }
private /*synchronized*/ void getLock(SimpleKVTransaction tx, byte[] minKey, byte[] maxKey, boolean write) { // Attempt to get the lock LockManager.LockResult lockResult; try { lockResult = this.lockManager.lock(tx.lockOwner, minKey, maxKey, write, tx.waitTimeout); } catch (InterruptedException e) { this.rollback(tx); Thread.currentThread().interrupt(); throw new RetryTransactionException(tx, "transaction interrupted while waiting to acquire lock", e); } // Check result switch (lockResult) { case SUCCESS: break; case WAIT_TIMEOUT_EXPIRED: this.rollback(tx); throw new RetryTransactionException(tx, "could not acquire lock after " + tx.waitTimeout + "ms"); case HOLD_TIMEOUT_EXPIRED: this.rollback(tx); throw new TransactionTimeoutException(tx, "transaction taking too long: hold timeout of " + this.lockManager.getHoldTimeout() + "ms has expired"); default: throw new RuntimeException("internal error"); } }
private void readObject(ObjectInputStream input) throws IOException, ClassNotFoundException { input.defaultReadObject(); this.log = LoggerFactory.getLogger(this.getClass()); this.lockManager = new LockManager(this); } }