El Tablestore SDK for Java ejecuta una transacción local para un valor de clave de partición específico, de modo que todas las escrituras de la transacción se confirman o se descartan en su totalidad. El nivel de aislamiento es Read Committed.
Requisitos previos
Instale Tablestore SDK for Java e inicialice el cliente.
Habilite las transacciones locales en la tabla. Puede habilitar esta función cuando create a table. Para habilitar las transacciones locales en una tabla existente o comprobar si la función está habilitada, envíe un ticket .
Descripción
Una transacción local se limita a un único valor de clave de partición. Las operaciones de lectura y escritura dentro de la transacción se vinculan mediante un ID de transacción y surten efecto de forma atómica al confirmarse, con un aislamiento de tipo Read Committed. Una transacción local consta de las siguientes tres fases:
startLocalTransactioninicia la transacción y devuelve el ID de transacción.Cada operación de lectura o escritura posterior asocia el ID mediante
setTransactionId(txnId).commitTransactionconfirma la transacción;abortTransactionla cancela.
Las operaciones compatibles dentro de una transacción son GetRow, PutRow, UpdateRow, DeleteRow, BatchWriteRow y GetRange.
public StartLocalTransactionResponse startLocalTransaction(StartLocalTransactionRequest request) throws TableStoreException, ClientException
public CommitTransactionResponse commitTransaction(CommitTransactionRequest request) throws TableStoreException, ClientException
public AbortTransactionResponse abortTransaction(AbortTransactionRequest request) throws TableStoreException, ClientException
public void setTransactionId(String transactionId)
En el siguiente ejemplo se inicia una transacción local en el valor de clave de partición pkvalue, se escribe una fila con la clave principal (pkvalue, 10001) y se confirma la transacción.
String tableName = "local_tx_demo";
// 1. Start a local transaction for the specified partition key value and obtain the transaction ID.
PrimaryKeyBuilder pkBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
pkBuilder.addPrimaryKeyColumn("pk1", PrimaryKeyValue.fromString("pkvalue"));
PrimaryKey partitionKey = pkBuilder.build();
StartLocalTransactionRequest startRequest =
new StartLocalTransactionRequest(tableName, partitionKey);
String txnId = client.startLocalTransaction(startRequest).getTransactionID();
// 2. Write a row within the transaction. You must specify the full primary key and include the transaction ID.
PrimaryKeyBuilder rowKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
rowKeyBuilder.addPrimaryKeyColumn("pk1", PrimaryKeyValue.fromString("pkvalue"));
rowKeyBuilder.addPrimaryKeyColumn("pk2", PrimaryKeyValue.fromLong(10001));
PrimaryKey rowKey = rowKeyBuilder.build();
RowPutChange rowPutChange = new RowPutChange(tableName, rowKey);
rowPutChange.addColumn(new Column("col1", ColumnValue.fromString("colvalue")));
rowPutChange.addColumn(new Column("col2", ColumnValue.fromLong(10)));
PutRowRequest putRequest = new PutRowRequest(rowPutChange);
putRequest.setTransactionId(txnId);
client.putRow(putRequest);
// 3. Commit the transaction to make all writes take effect. To discard changes, call abortTransaction() instead.
CommitTransactionRequest commitRequest = new CommitTransactionRequest(txnId);
client.commitTransaction(commitRequest);
Parámetros
Solicitud de inicio de transacción
StartLocalTransactionRequest contiene los siguientes parámetros.
|
Nombre |
Tipo |
Descripción |
|
tableName (obligatorio) |
String |
Nombre de la tabla de datos. |
|
primaryKey (obligatorio) |
PrimaryKey |
Valor de clave de partición que define el alcance de la transacción. Al iniciar una transacción local, especifique únicamente la primera columna de clave principal de la tabla. |
|
rowKeys (opcional) |
List<PrimaryKey> |
Claves principales de las filas que se bloquearán al iniciar la transacción. Llame a |
Solicitudes dentro de una transacción
Las solicitudes de lectura y escritura de datos utilizadas dentro de una transacción heredan de TxnRequest, que contiene el siguiente parámetro.
|
Nombre |
Tipo |
Descripción |
|
transactionId (obligatorio) |
String |
ID de la transacción local devuelto por |
Solicitud de confirmación o cancelación
CommitTransactionRequest y AbortTransactionRequest contienen el siguiente parámetro.
|
Nombre |
Tipo |
Descripción |
|
transactionID (obligatorio) |
String |
ID de la transacción local que se va a confirmar o cancelar. Especifique el ID al construir la solicitud. |
Respuesta
Resultado del inicio de transacción
StartLocalTransactionResponse contiene el siguiente campo específico de la operación.
|
Nombre |
Tipo |
Descripción |
|
transactionID |
String |
ID de la nueva transacción local. Llame a |
Límites
Las transacciones locales no son compatibles con columnas de clave principal de incremento automático.
Las transacciones locales utilizan bloqueo pesimista para el control de concurrencia. Durante una transacción, se mantiene un bloqueo de escritura en el valor de la clave de partición, por lo que solo tienen éxito las solicitudes de escritura que incluyen el ID de transacción.
Una transacción tiene una duración máxima de 60 segundos. Si dos operaciones consecutivas están separadas por más de 60 segundos, la transacción caduca y el servidor la descarta.
Solo una solicitud puede usar un ID de transacción a la vez. Las operaciones simultáneas que comparten el mismo ID fallan.
Cada solicitud de escritura dentro de una transacción debe usar el mismo valor de clave de partición que inició la transacción. Las solicitudes de lectura no tienen esta restricción.
Una sola transacción puede escribir hasta 4 MB de datos.
Si una escritura dentro de una transacción no especifica una versión de columna (marca de tiempo), el servidor genera la marca de tiempo en el momento de la escritura, no en el de la confirmación. Las reglas coinciden con las de una escritura normal.
Cuando una solicitud
BatchWriteRowincluye un ID de transacción, todas las filas deben dirigirse a la tabla en la que se inició la transacción.Si la transacción no contiene escrituras, la confirmación y la cancelación tienen el mismo efecto.
Una solicitud de lectura o escritura con errores que incluye un ID de transacción no finaliza la transacción. Puede aplicar una directiva de reintentos o cancelar la transacción explícitamente.
Ejemplos
Lectura de una fila dentro de una transacción
Cree una transacción de solo lectura para un valor de clave de partición específico y lea una fila.
String tableName = "local_tx_demo";
// 1. Start a local transaction for the specified partition key value.
PrimaryKeyBuilder pkBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
pkBuilder.addPrimaryKeyColumn("pk1", PrimaryKeyValue.fromString("pkvalue"));
PrimaryKey partitionKey = pkBuilder.build();
StartLocalTransactionRequest startRequest =
new StartLocalTransactionRequest(tableName, partitionKey);
String txnId = client.startLocalTransaction(startRequest).getTransactionID();
// 2. Read a row within the transaction. You must specify the full primary key and include the transaction ID.
PrimaryKeyBuilder rowKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
rowKeyBuilder.addPrimaryKeyColumn("pk1", PrimaryKeyValue.fromString("pkvalue"));
rowKeyBuilder.addPrimaryKeyColumn("pk2", PrimaryKeyValue.fromLong(10001));
PrimaryKey rowKey = rowKeyBuilder.build();
SingleRowQueryCriteria criteria = new SingleRowQueryCriteria(tableName, rowKey);
criteria.setMaxVersions(1);
GetRowRequest getRequest = new GetRowRequest(criteria);
getRequest.setTransactionId(txnId);
GetRowResponse getResponse = client.getRow(getRequest);
// 3. Commit or abort the transaction. For a read-only transaction, both have the same effect and release the transaction.
CommitTransactionRequest commitRequest = new CommitTransactionRequest(txnId);
client.commitTransaction(commitRequest);
Row row = getResponse.getRow();
System.out.println(row);
Escritura por lotes de varias filas dentro de una transacción
Asocie el ID de transacción a una escritura por lotes mediante una llamada a BatchWriteRowRequest.setTransactionId(txnId). El valor de clave de partición de cada fila debe coincidir con el valor utilizado al iniciar la transacción, y la confirmación aplica todos los cambios de forma atómica.
String tableName = "local_tx_demo";
// 1. Start a local transaction. The partition key value of every row in the batch must match this value.
PrimaryKeyBuilder pkBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
pkBuilder.addPrimaryKeyColumn("pk1", PrimaryKeyValue.fromString("pkvalue"));
PrimaryKey partitionKey = pkBuilder.build();
StartLocalTransactionRequest startRequest =
new StartLocalTransactionRequest(tableName, partitionKey);
String txnId = client.startLocalTransaction(startRequest).getTransactionID();
// 2. Build the batch write request and include the transaction ID.
BatchWriteRowRequest batchRequest = new BatchWriteRowRequest();
batchRequest.setTransactionId(txnId);
// Add multiple rows (pk1 of every row must equal the transaction's partition key value "pkvalue").
for (long pk2 = 20001; pk2 <= 20003; pk2++) {
PrimaryKeyBuilder rowKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
rowKeyBuilder.addPrimaryKeyColumn("pk1", PrimaryKeyValue.fromString("pkvalue"));
rowKeyBuilder.addPrimaryKeyColumn("pk2", PrimaryKeyValue.fromLong(pk2));
RowPutChange rowPutChange = new RowPutChange(tableName, rowKeyBuilder.build());
rowPutChange.addColumn(new Column("col1", ColumnValue.fromString("batch_" + pk2)));
batchRequest.addRowChange(rowPutChange);
}
BatchWriteRowResponse batchResponse = client.batchWriteRow(batchRequest);
System.out.println("Batch all succeeded: " + batchResponse.isAllSucceed());
// 3. Commit the transaction so that all batch writes take effect atomically.
CommitTransactionRequest commitRequest = new CommitTransactionRequest(txnId);
client.commitTransaction(commitRequest);