Após ativar local transactions em uma tabela de dados, crie uma local transaction com base em um valor de chave de partição especificado e execute operações de leitura e gravação nos dados da transação. Local transactions oferecem suporte a operações atômicas de leitura e gravação em uma ou mais linhas.
Scenarios
O recurso de local transaction permite executar operações atômicas para ler e gravar uma ou mais linhas. Veja a seguir exemplos de cenários de uso:
Simple scenarios: Read and write data
Use os dois métodos a seguir para executar operações de leitura, modificação e gravação (RMW). Cada método possui limitações específicas.
Atualização condicional: processa apenas uma solicitação que envolve uma única linha por vez. Não é possível usar este método para processar solicitações que envolvem múltiplas linhas de dados ou múltiplas operações de gravação. Para mais informações, consulte Conditional updates.
Contador atômico: processa apenas uma solicitação que envolve uma única linha por vez e oferece suporte somente ao incremento de valores de colunas. Para mais informações, consulte Use the atomic counter feature.
Para contornar as limitações descritas acima, crie uma local transaction e execute operações RMW nos dados dentro do intervalo especificado pelo valor da chave de partição.
Chame a operação StartLocalTransaction para criar uma local transaction com base no valor da chave de partição especificado e obtenha o ID da local transaction.
Chame a operação GetRow ou GetRange para ler os dados. A solicitação deve conter o ID da local transaction.
Modifique os dados no cliente.
Chame a operação PutRow, UpdateRow, DeleteRow ou BatchWriteRow para gravar os dados modificados. A solicitação deve conter o ID da local transaction.
Chame a operação CommitTransaction para confirmar a local transaction.
Complex scenario: mailbox scenario
Crie uma local transaction para executar operações atômicas nos e-mails de um usuário específico.
Para usar o recurso de local transaction corretamente, crie duas tabelas de índice em uma tabela de dados. A tabela a seguir lista as colunas de chave primária dessas tabelas. Na tabela, a coluna Type distingue a tabela de dados das tabelas de índice. Cada linha de índice usa a coluna IndexField para armazenar um campo com significado específico, enquanto a tabela de dados não contém a coluna IndexField.
|
Table |
Primary key column |
|||
|
UserID |
Type |
IndexField |
MailID |
|
|
Tabela de dados |
ID do usuário |
"Main" |
N/A |
ID do e-mail |
|
Tabela de índice de pastas |
ID do usuário |
"Folder" |
$Folder |
ID do e-mail |
|
Tabela de índice SendTime |
ID do usuário |
"SendTime" |
$SendTime |
ID do e-mail |
Com o recurso de local transaction, você pode executar as seguintes operações nos e-mails.
Scenario 1: List the last 100 emails sent by a user
Use o ID do usuário para criar uma local transaction e obtenha o ID da transação.
Chame a operação GetRange para consultar 100 e-mails na tabela de índice SendTime. A solicitação deve conter o ID da local transaction.
Chame a operação BatchGetRow para consultar as informações detalhadas dos 100 e-mails na tabela de dados. A solicitação deve conter o ID da local transaction.
Chame a operação CommitTransaction para confirmar a local transaction ou chame a operação AbortTransaction para cancelá-la.
Scenario 2: Transfer all emails in a folder to another folder
Use o ID do usuário para criar uma local transaction e obtenha o ID da transação.
Chame a operação GetRange para consultar e-mails na tabela de índice Folder. A solicitação deve conter o ID da local transaction.
-
Chame a operação BatchWriteRow para executar operações de gravação na tabela de índice Folder. A solicitação deve conter o ID da local transaction.
A cada transferência de e-mail, duas linhas são gravadas: remove-se a linha que indica a pasta original da tabela de índice Folder e adiciona-se uma nova linha que indica a pasta de destino.
Chame a operação CommitTransaction para confirmar a local transaction.
Scenario 3: Count the numbers of read emails and unread emails in a folder
Use o ID do usuário para criar uma local transaction e obtenha o ID da transação.
Chame a operação GetRange para consultar e-mails na tabela de índice Folder. A solicitação deve conter o ID da local transaction.
Chame a operação BatchGetRow para consultar o status de leitura de cada e-mail na tabela de dados.
Chame a operação CommitTransaction para confirmar a local transaction ou chame a operação AbortTransaction para cancelá-la.
Esta solução não é a ideal. Neste cenário, adicione mais tabelas de índice para acelerar as consultas. O recurso de local transaction garante a consistência de status entre a tabela de dados e as tabelas de índice, simplificando o desenvolvimento. Por exemplo, a solução de contagem de e-mails descrita acima exige a leitura de muitos e-mails e gera alto custo operacional. Para reduzir esse custo e acelerar as consultas, use uma nova tabela de índice para armazenar as contagens de e-mails lidos e não lidos.
Before you begin
É necessário ativar local transactions ao criar uma tabela de dados. Use o console do Tablestore, o Tablestore SDK for Java V5.11.0 ou posterior, ou a versão mais recente do Tablestore SDK for Go. Para mais informações, consulte Create a data table.
Se precisar de local transactions em uma tabela de dados existente, mas não tiver ativado o recurso durante a criação da tabela, envie um ticket. Você também pode entrar no grupo DingTalk 36165029092 (Tablestore Technical Discussion Group-3) para obter assistência
Usage notes
Não é possível usar o recurso de coluna de chave primária com incremento automático e o recurso de local transaction ao mesmo tempo.
O bloqueio pessimista controla as operações concorrentes em uma local transaction.
-
O período de validade de uma local transaction pode ser de até 60 segundos.
Se uma local transaction não for confirmada ou cancelada dentro de 60 segundos, o servidor do Tablestore determina que a transação expirou e a cancela automaticamente.
Uma transação pode ser criada no servidor do Tablestore mesmo que um erro de timeout seja retornado. Nesse caso, reenvie a solicitação de criação após a expiração da transação criada.
Se uma local transaction não for confirmada, ela pode se tornar inválida. Nesse caso, repita as operações nessa transação.
Quando nenhuma operação de gravação é executada nos dados de uma local transaction, as operações de confirmação e cancelamento têm o mesmo efeito.
-
O Tablestore impõe os seguintes limites às operações de leitura e gravação nos dados de uma local transaction:
O ID da local transaction não pode ser usado para acessar dados fora do intervalo especificado pelo valor da chave de partição utilizado para criar a transação.
Os valores da chave de partição de todas as solicitações de gravação na mesma transação devem ser iguais ao valor da chave de partição usado para criar a transação. Essa restrição não se aplica a solicitações de leitura.
Uma local transaction pode ser usada por apenas uma solicitação por vez. Enquanto a local transaction estiver em uso, outras operações que utilizem o mesmo ID de local transaction falharão.
-
O intervalo máximo entre duas operações consecutivas de leitura ou gravação nos dados de uma local transaction é de 60 segundos.
Se nenhuma operação de leitura ou gravação for executada nos dados de uma local transaction por mais de 60 segundos, o servidor do Tablestore determina que a transação expirou e a cancela automaticamente.
É 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 em 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 atribuirá automaticamente um número de versão a ela no momento em que for gravada na transação, e não no momento em que a transação for confirmada.
Se uma solicitação BatchWriteRow incluir um ID de local transaction, todas as linhas da solicitação só poderão ser gravadas na tabela correspondente ao ID da local transaction.
Ao usar uma local transaction, um bloqueio de gravação é adicionado aos dados do valor da chave de partição com base no qual a transação foi criada. Apenas solicitações de gravação que contenham o ID da local transaction e sejam iniciadas para gravar dados nessa transação serão bem-sucedidas. Outras solicitações não transacionais ou solicitações de gravação que contenham IDs de outras local transactions falharão. Os dados da local transaction são desbloqueados quando a transação é confirmada, cancelada ou expira.
Uma local transaction permanece válida mesmo que uma solicitação de leitura ou gravação com o ID da local transaction seja rejeitada. Especifique uma regra de nova tentativa para reenviar a solicitação ou cancele a transação.
Procedure
Gerencie local transactions exclusivamente por meio dos Tablestore SDKs.
Para usar local transactions, crie uma local transaction para um valor de chave de partição, execute operações de leitura e gravação dentro da transação e, por fim, confirme ou cancele a transação conforme necessário. Os exemplos a seguir utilizam o Tablestore SDK for Java.
Use the local transaction feature to write a data row
O exemplo a seguir cria uma local transaction para um valor de chave de partição especificado de uma tabela e grava uma linha dentro da local transaction.
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);
Use the local transaction feature to read a data row
O exemplo a seguir cria uma local transaction para um valor de chave de partição especificado de uma tabela e lê uma linha dentro da local transaction.
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);
SDK integration
Use local transactions com os seguintes SDKs.
Billing
Cada operação StartLocalTransaction, CommitTransaction e AbortTransaction consome uma unidade de capacidade (CU) de gravação.
As operações de leitura e gravação são cobradas da mesma forma que solicitações padrão de leitura e gravação. Para mais informações sobre faturamento, consulte Billing overview.
Error codes
|
Error code |
Description |
|
OTSRowOperationConflict |
O valor da chave de partição já está ocupado por outra local transaction. |
|
OTSSessionNotExist |
A transação correspondente ao ID de transação especificado não existe, ou a transação é inválida ou expirou. |
|
OTSSessionBusy |
A última solicitação na transação está incompleta. |
|
OTSOutOfTransactionDataSizeLimit |
O volume de dados na transação excede o limite máximo. |
|
OTSDataOutOfRange |
A operação de dados está além do intervalo especificado pelo valor da chave de partição usado para criar a transação. |