/** * @param maxRetries max number of retries * @param delayInMs delay between retries in milliseconds * @return RetryStrategy that retries transaction execution when transaction fails with * {@link TransactionConflictException} */ public static RetryStrategy retryOnConflict(int maxRetries, long delayInMs) { return new RetryOnConflictStrategy(maxRetries, delayInMs); }
@Override public void updateTx(Transaction tx) { for (TransactionAware txAware : this) { txAware.updateTx(tx); } }
@Override public boolean commitTx() throws Exception { boolean success = true; for (TransactionAware txAware : this) { success = success && txAware.commitTx(); } return success; }
private <I, O> O executeOnce(Function<I, O> function, I input) throws TransactionFailureException { TransactionContext txContext = new TransactionContext(txClient, txAwares); txContext.start(); O o = null; try { o = function.apply(input); } catch (Throwable e) { txContext.abort(new TransactionFailureException("Transaction function failure for transaction. ", e)); // abort will throw } // will throw if smth goes wrong txContext.finish(); return o; } }
/** * Aborts the given transaction, and rolls back all data set changes. If rollback fails, * the transaction is invalidated. If an exception is caught during rollback, the exception * is rethrown wrapped in a TransactionFailureException, after all remaining TransactionAwares have * completed rollback. * * @throws TransactionFailureException for any exception that is encountered. */ public void abort() throws TransactionFailureException { abort(null); }
/** * Returns the maximum timestamp to use for time-range operations, based on the given transaction. * @param tx The current transaction * @return The maximum timestamp (exclusive) to use for time-range operations */ public static long getMaxVisibleTimestamp(Transaction tx) { // NOTE: +1 here because we want read up to writepointer inclusive, but timerange's end is exclusive // however, we also need to guard against overflow in the case write pointer is set to MAX_VALUE return tx.getWritePointer() < Long.MAX_VALUE ? tx.getWritePointer() + 1 : tx.getWritePointer(); }
/** * Start a short transaction with the default timeout. */ public Transaction startShort() { return startShort(defaultTimeout); }
@Override public void startTx(Transaction tx) { for (TransactionAware txAware : this) { txAware.startTx(tx); } }
private void doCheckpoint(long newWritePointer, long parentWritePointer) { InProgressTx existingTx = inProgress.get(parentWritePointer); existingTx.addCheckpointWritePointer(newWritePointer); advanceWritePointer(newWritePointer); }
private TransactionExecutor getExecutorWithNoRetry() { return new DefaultTransactionExecutor(txClient, txAwares, RetryStrategies.noRetries()); }
@Override public O call() throws Exception { return execute(callable); } });
/** * Returns whether the given version was written by the current transaction. * * @param version the data version * @return true if version was written by current transaction, false otherwise. */ public boolean isCurrentWrite(long version) { return writePointer == version || txId == version || isCheckpoint(version); }
@Override public InputStream getSnapshotInputStream() throws TransactionCouldNotTakeSnapshotException { throw new TransactionCouldNotTakeSnapshotException( "Snapshot not implemented in detached transaction system client"); }
@Override public Void apply(Void input) throws Exception { subroutine.apply(); return null; } }, null);
private <I, O> O executeOnce(Function<I, O> function, I input) throws TransactionFailureException { TransactionContext txContext = new TransactionContext(txClient, txAwares); txContext.start(); O o = null; try { o = function.apply(input); } catch (Throwable e) { txContext.abort(new TransactionFailureException("Transaction function failure for transaction. ", e)); // abort will throw } // will throw if smth goes wrong txContext.finish(); return o; } }
@Override public O call() throws Exception { return execute(function, input); } });
/** * Returns whether the given version was written by the current transaction. * * @param version the data version * @return true if version was written by current transaction, false otherwise. */ public boolean isCurrentWrite(long version) { return writePointer == version || txId == version || isCheckpoint(version); }
@Override public I call() throws Exception { execute(procedure, input); return null; } });
@Override public Object call() throws Exception { execute(subroutine); return null; } });
@Override public O call() throws Exception { return execute(callable); } });