Após ativar o recurso de transação local para uma tabela de dados, você pode criar uma transação local com escopo em um valor de chave de partição e executar operações de leitura e gravação nela. Todas as operações em uma transação são bem-sucedidas ou falham juntas, com bloqueio pessimista para controle de concorrência. O nível de isolamento é Read Committed.
Pré-requisitos
Antes de começar, verifique se você possui:
Um cliente inicializado. Para mais informações, consulte Inicializar um cliente do Tablestore.
-
Uma tabela de dados com o recurso de transação local ativado.
nullSe você não ativou o recurso de transação local ao criar a tabela de dados e deseja ativá-lo posteriormente, envie um ticket.
Como funciona
Uma transação local tem escopo em um único valor de chave de partição. Todas as leituras e gravações em uma transação compartilham o mesmo ID de transação, que o Tablestore usa para garantir isolamento e atomicidade.
Chame
StartLocalTransactioncom um valor de chave de partição para criar uma transação e obter o ID da transação.-
Execute operações de leitura e gravação na transação. Passe o ID da transação em cada solicitação.
Operações compatíveis: GetRow, PutRow, DeleteRow, UpdateRow, BatchWriteRow e GetRange.
Chame
CommitTransactionpara aplicar todas as alterações ouAbortTransactionpara descartá-las.
Notas de uso
-
Não é possível usar o recurso de coluna de chave primária com incremento automático e o recurso de transação local ao mesmo tempo.
-
O bloqueio pessimista controla as operações simultâneas em uma transação local.
-
O período de validade de uma transação local pode ser de até 60 segundos.
Se uma transação local não for confirmada ou abortada em 60 segundos, o servidor do Tablestore considera que a transação local expirou e a aborta.
-
Uma transação pode ser criada no servidor do Tablestore mesmo quando um erro de tempo limite é retornado. Nesse caso, reenvie a solicitação de criação de transação após a transação criada expirar.
-
Se uma transação local não for confirmada, ela pode se tornar inválida. Nesse caso, repita as operações nessa transação.
-
Se nenhuma operação de gravação for executada nos dados de uma transação local, as operações de commit e abort terão o mesmo efeito.
-
O Tablestore impõe os seguintes limites às operações de leitura e gravação nos dados de uma transação local:
-
O ID da transação local não pode ser usado para acessar dados fora do intervalo especificado com base no valor de chave de partição usado para criar a transação.
-
Os valores de chave de partição de todas as solicitações de gravação na mesma transação devem ser iguais ao valor de chave de partição usado para criar a transação. Esse limite não se aplica às solicitações de leitura.
-
Uma transação local pode ser usada por apenas uma solicitação por vez. Quando a transação local está em uso, outras operações que usam o mesmo ID de transação local falham.
-
O intervalo máximo entre duas operações consecutivas de leitura ou gravação nos dados de uma transação local é de 60 segundos.
Se nenhuma operação de leitura ou gravação for executada nos dados de uma transação local por mais de 60 segundos, o servidor do Tablestore considera que a transação expirou e a aborta.
-
É possível gravar até 4 MB de dados em cada transação. O volume de dados gravados em cada transação é calculado da mesma forma que uma solicitação de gravação regular.
-
Se você não especificar um número de versão para uma célula, o servidor do Tablestore atribui automaticamente um número de versão à célula da forma habitual quando a célula é gravada na transação, e não quando a transação é confirmada.
-
Se uma solicitação BatchWriteRow incluir um ID de transação local, todas as linhas na solicitação só poderão ser gravadas na tabela correspondente ao ID da transação local.
-
Ao usar uma transação local, um bloqueio de gravação é adicionado aos dados do valor de chave de partição com base no qual a transação local foi criada. Somente solicitações de gravação que contêm o ID da transação local e são iniciadas para gravar dados na transação local podem ser bem-sucedidas. Outras solicitações não transacionais ou solicitações de gravação que contêm IDs de outras transações locais e são iniciadas para gravar dados na transação local falham. Os dados na transação local são desbloqueados quando a transação é confirmada, abortada ou quando expira.
-
Uma transação local permanece válida mesmo que uma solicitação de leitura ou gravação com o ID da transação local seja rejeitada. Especifique uma regra de nova tentativa para reenviar a solicitação ou aborte a transação.
-
Como verificar se as transações locais estão ativadas para uma tabela de dados?
O console do Tablestore não exibe o status de transação local de uma tabela de dados. O comando desc da CLI exporta o esquema da tabela, mas não inclui o atributo de transação local.
Para confirmar se as transações locais estão ativadas para uma tabela de dados, use um SDK para chamar a operação DescribeTable. A resposta inclui os metadados completos da tabela, incluindo o status de transação local.
Se você não tem acesso à operação DescribeTable, verifique se setLocalTxnEnabled(true) foi chamado no código usado para criar a tabela de dados ou envie um ticket para confirmar se esse recurso foi ativado anteriormente.
Parâmetros
|
Parâmetro |
Descrição |
|
TableName |
O nome da tabela de dados. |
|
PrimaryKey |
A chave primária da tabela de dados.
|
|
TransactionId |
O identificador exclusivo da transação local. Passe esse ID em todas as solicitações de leitura e gravação na transação. |
Código de exemplo
Use o recurso de transação local para gravar uma linha de dados
O exemplo a seguir cria uma transação local com escopo em um valor de chave de partição e grava uma linha nela. Todas as etapas usam o mesmo ID de transação, e a transação é confirmada no final.
private static void transactionPutRow(SyncClient client) {
String tableName = "<TABLE_NAME>";
// 1. Create a local transaction scoped to a 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. Write a row within the transaction.
// All primary key columns must be specified.
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); // Pass the transaction ID.
client.putRow(putRequest);
// 3. Commit the transaction to apply all changes.
// To discard all changes instead, call abortTransaction().
CommitTransactionRequest commitRequest = new CommitTransactionRequest(txnId);
client.commitTransaction(commitRequest);
// AbortTransactionRequest abortRequest = new AbortTransactionRequest(txnId);
// client.abortTransaction(abortRequest);
}
Use o recurso de transação local para ler uma linha de dados
O exemplo a seguir cria uma transação local e lê uma linha nela. Para transações somente leitura, confirmar e abortar têm o mesmo efeito — ambas liberam a transação.
private static void transactionGetRow(SyncClient client) {
String tableName = "exampletabled";
// 1. Create a local transaction scoped to a partition key value.
PrimaryKeyBuilder pkBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
pkBuilder.addPrimaryKeyColumn("pk1", PrimaryKeyValue.fromString("111"));
PrimaryKey partitionKey = pkBuilder.build();
StartLocalTransactionRequest startRequest =
new StartLocalTransactionRequest(tableName, partitionKey);
String txnId = client.startLocalTransaction(startRequest).getTransactionID();
// 2. Read a row within the transaction.
// All primary key columns must be specified.
PrimaryKeyBuilder rowKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
rowKeyBuilder.addPrimaryKeyColumn("pk1", PrimaryKeyValue.fromString("111"));
rowKeyBuilder.addPrimaryKeyColumn("pk2", PrimaryKeyValue.fromLong(10001));
PrimaryKey rowKey = rowKeyBuilder.build();
SingleRowQueryCriteria criteria = new SingleRowQueryCriteria(tableName, rowKey);
criteria.setMaxVersions(1); // Read the latest version.
GetRowRequest getRequest = new GetRowRequest(criteria);
getRequest.setTransactionId(txnId); // Pass the transaction ID.
GetRowResponse getRowResponse = client.getRow(getRequest);
// 3. Commit or abort — for read-only transactions, both release the transaction.
CommitTransactionRequest commitRequest = new CommitTransactionRequest(txnId);
client.commitTransaction(commitRequest);
// AbortTransactionRequest abortRequest = new AbortTransactionRequest(txnId);
// client.abortTransaction(abortRequest);
// Print the row data.
Row row = getRowResponse.getRow();
System.out.println("Row data:");
System.out.println(row);
}
Próximas etapas
Para gravar várias linhas ou ler um intervalo de linhas em uma transação local, crie a transação usando StartLocalTransaction, siga o código de exemplo no tópico Gravar dados ou Ler dados e passe o ID da transação em cada solicitação.