com.palantir.atlasdb.transaction.api.Transaction Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of atlasdb-api Show documentation
Show all versions of atlasdb-api Show documentation
Palantir open source project
/*
* (c) Copyright 2018 Palantir Technologies Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.palantir.atlasdb.transaction.api;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.errorprone.annotations.RestrictedApi;
import com.palantir.atlasdb.keyvalue.api.BatchColumnRangeSelection;
import com.palantir.atlasdb.keyvalue.api.Cell;
import com.palantir.atlasdb.keyvalue.api.ColumnRangeSelection;
import com.palantir.atlasdb.keyvalue.api.ColumnSelection;
import com.palantir.atlasdb.keyvalue.api.RangeRequest;
import com.palantir.atlasdb.keyvalue.api.RowResult;
import com.palantir.atlasdb.keyvalue.api.TableReference;
import com.palantir.atlasdb.spi.KeyValueServiceConfig;
import com.palantir.atlasdb.transaction.api.annotations.ReviewedRestrictedApiUsage;
import com.palantir.atlasdb.transaction.api.exceptions.MoreCellsPresentThanExpectedException;
import com.palantir.atlasdb.transaction.service.TransactionService;
import com.palantir.common.annotation.Idempotent;
import com.palantir.common.base.BatchingVisitable;
import com.palantir.lock.watch.ChangeMetadata;
import com.palantir.util.result.Result;
import java.util.Iterator;
import java.util.Map;
import java.util.NavigableMap;
import java.util.Set;
import java.util.function.BiFunction;
import java.util.stream.Stream;
/**
* Provides the methods for a transaction with the key-value store.
*
* In general: users may assume that if maps (including sorted maps) keyed on byte[] are returned to the user,
* they may be accessed via any byte array that is equivalent in terms of
* {@link java.util.Arrays#equals(byte[], byte[])}.
*
* Throughout this class, methods that return structures that may not perform all of their loading upfront (batching
* visitables, iterables, streams and futures, for instance) _must_ be used strictly within the scope of the
* transaction. Concretely, this means that results must be retrieved before exiting the transaction - in the case of
* streams and iterators, this means that you must collect the results before exiting; in the case of futures, you must
* await all asynchronous calls before returning from the transaction.
*
* @see TransactionManager
*/
public interface Transaction {
/**
* Returns a mapping of rows to {@link RowResult}s within {@code tableRef} for the specified {@code rows}, loading
* columns according to the provided {@link ColumnSelection}. Duplicate rows are permitted (but there will be just
* one key-value pair for that row in the returned {@link NavigableMap}).
*
* The returned {@link NavigableMap} is sorted on the byte order of row keys; the ordering of the input parameter
* {@code rows} is irrelevant.
*
* If there are rows with no cells matching the provided {@link ColumnSelection}, they will not be present in the
* {@link Map#keySet()} of the output map at all. This accounts for writes and deletes done in this transaction:
* a row written to in this transaction will be present, and a row which is deleted in this transaction will be
* absent.
*
* @param tableRef table to load rows from
* @param rows rows to be loaded
* @param columnSelection columns to load from the given rows
* @return a mapping of rows to the columns matching the provided column selection
*/
@Idempotent
NavigableMap> getRows(
TableReference tableRef, Iterable rows, ColumnSelection columnSelection);
/**
* Returns a mapping of requested {@code rows} to corresponding columns from the queried table.
* Only columns matching the provided predicate will be returned, and the single predicate provided applies across
* all of the rows. Users should provide unique rows: behaviour is undefined if this is not the case.
*
* The returned {@link BatchingVisitable}s are guaranteed to return cells matching the predicate. These are sorted
* by column on byte ordering.
*
* It is guaranteed that the {@link Map#keySet()} of the returned map has a corresponding element for each of the
* input {@code rows}, even if there are rows where no columns match the predicate.
*
* Batching visitables must be used strictly within the scope of the transaction.
*
* @param tableRef table to load values from
* @param rows unique rows to apply the column range selection to
* @param columnRangeSelection range of columns and batch size to load for each of the rows provided
* @return a mapping of rows to cells matching the predicate in the row, following the ordering outlined above
*/
@Idempotent
Map>> getRowsColumnRange(
TableReference tableRef, Iterable rows, BatchColumnRangeSelection columnRangeSelection);
/**
* Returns a single iterator over the cell-value pairs in {@code tableRef} for the specified {@code rows}, where the
* columns fall within the provided {@link ColumnRangeSelection}. The single provided {@link ColumnRangeSelection}
* applies to all of the rows.
*
* The returned iterator is guaranteed to return cell-value pairs in a lexicographic ordering over rows and columns
* where rows are sorted according to the provided {@code rows} {@link Iterable} and then columns on byte ordering.
* If the {@link Iterable} does not have a stable ordering (i.e. iteration order can change across iterators
* returned) then the returned iterator is sorted lexicographically with columns sorted on byte ordering, but
* the ordering of rows is undefined.
*
* Iterators must be used strictly within the scope of the transaction.
*
* @param tableRef table to load values from
* @param rows unique rows to apply the column range selection to
* @param columnRangeSelection range of columns to load for each of the rows provided
* @param batchHint number of columns that should be loaded from the underlying database at once
* @return an iterator over cell-value pairs, guaranteed to follow the ordering outlined above
* @throws IllegalArgumentException if {@code rows} contains duplicates
*/
@Idempotent
Iterator> getRowsColumnRange(
TableReference tableRef, Iterable rows, ColumnRangeSelection columnRangeSelection, int batchHint);
/**
* Returns a mapping of rows to {@link Iterator}s over cell-value pairs within {@code tableRef} for the specified
* {@code rows}, where the columns fall within the provided {@link BatchColumnRangeSelection}. The single provided
* {@link BatchColumnRangeSelection} applies to all of the rows.
*
* The returned iterators are guaranteed to return cells matching the predicate. These are sorted by column on
* byte ordering.
*
* It is guaranteed that the {@link Map#keySet()} of the returned map has a corresponding element for each of the
* input {@code rows}, even if there are rows where no columns match the predicate.
*
* Iterators must be used strictly within the scope of the transaction.
*
* @param tableRef table to load values from
* @param rows unique rows to apply the column range selection to
* @param columnRangeSelection range of columns and batch size to load for each of the rows provided
* @return a mapping of rows to cells matching the predicate in the row, following the ordering outlined above
* @throws IllegalArgumentException if {@code rows} contains duplicates
*/
@Idempotent
Map>> getRowsColumnRangeIterator(
TableReference tableRef, Iterable rows, BatchColumnRangeSelection columnRangeSelection);
/**
* Returns an iterator over cell-value pairs within {@code tableRef} for the specified {@code rows}, where the
* columns fall within the provided {@link BatchColumnRangeSelection}.The single provided
* {@link BatchColumnRangeSelection} applies to all of the rows. The cells for a row appear exactly once even if
* the same row is included multiple times in {@code rows}.
*
* The returned iterator is guaranteed to contain cells sorted first in lexicographical order of column on byte
* ordering, then in order of row, where rows are sorted according to the provided {@code rows} {@link Iterable}.
* If the {@link Iterable} does not have a stable ordering (i.e. iteration order can change across iterators
* returned) then the returned iterator is sorted lexicographically with columns sorted on byte ordering, but the
* ordering of rows is undefined. In case of duplicate rows, the ordering is based on the first occurrence of
* the row.
*
* Iterators must be used strictly within the scope of the transaction.
*
* @param tableRef table to load values from
* @param rows unique rows to apply column range selection to
* @param batchColumnRangeSelection range of columns and batch size to load for all rows provided
* @return an iterator over cell-value pairs, guaranteed to follow the ordering outlined above
*/
@Idempotent
Iterator> getSortedColumns(
TableReference tableRef, Iterable rows, BatchColumnRangeSelection batchColumnRangeSelection);
/**
* Gets the values associated for each cell in {@code cells} from table specified by {@code tableRef}.
*
* @param tableRef the table from which to get the values
* @param cells the cells for which we want to get the values
* @return a {@link Map} from {@link Cell} to {@code byte[]} representing cell/value pairs
*/
@Idempotent
Map get(TableReference tableRef, Set cells);
/**
* Similar to {@link #get(TableReference, Set)}, but allows the caller to specify the number of expected present
* cells. This is important to allow clients that might have schemas that guarantees only a subset of the columns
* are present to still benefit from being able to skip the immutable timestamp lock check on non-empty reads of
* thoroughly swept tables.
*
* If we find values for the exact number of expected present cells, we'll skip the immutable timestamp lock check.
* If we find less values, we'll perform the immutable timestamp lock check.
* If we find more values, we'll throw an exception, as it means that either:
* 1 - There is a bug in the implementation of this method.
* 2 - The client is making an incorrect assumption about the maximum number of values that will be present, and
* we could have returned empty values in the past when we should have not.
*
* WARNING: This method should only be used if you REALLY know what you're doing. Otherwise, you could have
* correctness issues by reading empty values when one is actually present if you don't use this method correctly.
*
* @param tableRef the table from which to get the values
* @param cells the cells for which we want to get the values
* @param expectedNumberOfPresentCells the maximum number of cells that are expected to be present.
* @return a {@link Map} from {@link Cell} to {@code byte[]} representing cell/value pairs
*/
@RestrictedApi(
explanation = "This API is only meant to be used by AtlasDb proxies that want to make usage of the "
+ "performance improvement of skipping the immutable timestamp lock check on non-empty reads of "
+ "thoroughly swept tables, but their schema won't allow them to have non empty reads due to "
+ "columns being mutually exclusive, for example. So this API gives them a good way to specifying "
+ "the max number of values they'd ever expect in a get, which when met would allow them to skip "
+ "the lock check. Wrong usage of this API can cause correctness issues, so it's restricted.",
link = "https://github.com/palantir/atlasdb/pull/6655",
allowedOnPath = ".*/src/test/.*", // Unsafe behavior in tests is ok.
allowlistAnnotations = {ReviewedRestrictedApiUsage.class})
@Idempotent
Result | |