Le SDK Tablestore pour Java exécute une transaction locale pour une valeur de clé de partition donnée. Toutes les écritures de la transaction sont soit validées, soit abandonnées. Le niveau d'isolation est Read Committed.
Prérequis
Installez le SDK Tablestore pour Java et initialisez le client.
Activez les transactions locales sur la table. Vous pouvez activer cette fonctionnalité lors de la création d'une table. Pour activer les transactions locales sur une table existante ou vérifier si la fonctionnalité est activée, soumettez un ticket .
Description
Une transaction locale est limitée à une seule valeur de clé de partition. Les lectures et les écritures au sein de la transaction sont liées par un ID de transaction et prennent effet de manière atomique lors de la validation, avec une isolation Read Committed. Une transaction locale comporte les trois étapes suivantes :
startLocalTransactiondémarre la transaction et renvoie l'ID de transaction.Chaque lecture ou écriture suivante associe l'ID à l'aide de
setTransactionId(txnId).commitTransactionvalide la transaction ;abortTransactionl'abandonne.
Les opérations prises en charge au sein d'une transaction sont GetRow, PutRow, UpdateRow, DeleteRow, BatchWriteRow et 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)
L'exemple suivant démarre une transaction locale sur la valeur de clé de partition pkvalue, écrit une ligne avec la clé primaire (pkvalue, 10001) et valide la 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);
Paramètres
Requête de démarrage de transaction
StartLocalTransactionRequest contient les paramètres suivants.
|
Nom |
Type |
Description |
|
tableName (obligatoire) |
String |
Le nom de la table de données. |
|
primaryKey (obligatoire) |
PrimaryKey |
La valeur de la clé de partition qui définit la portée de la transaction. Lorsque vous démarrez une transaction locale, spécifiez uniquement la première colonne de clé primaire de la table. |
|
rowKeys (facultatif) |
List<PrimaryKey> |
Les clés primaires des lignes à verrouiller au démarrage de la transaction. Appelez |
Requêtes au sein d'une transaction
Les requêtes de lecture et d'écriture de données utilisées au sein d'une transaction héritent de TxnRequest, qui contient le paramètre suivant.
|
Nom |
Type |
Description |
|
transactionId (obligatoire) |
String |
L'ID de transaction locale renvoyé par |
Requête de validation ou d'abandon
CommitTransactionRequest et AbortTransactionRequest contiennent le paramètre suivant.
|
Nom |
Type |
Description |
|
transactionID (obligatoire) |
String |
L'ID de transaction locale à valider ou à abandonner. Spécifiez l'ID lors de la construction de la requête. |
Réponse
Résultat du démarrage de transaction
StartLocalTransactionResponse contient le champ spécifique à l'opération suivant.
|
Nom |
Type |
Description |
|
transactionID |
String |
L'ID de la nouvelle transaction locale. Appelez |
Limites
Les transactions locales ne sont pas compatibles avec les colonnes de clé primaire à incrémentation automatique.
Les transactions locales utilisent le verrouillage pessimiste pour le contrôle de la concurrence. Pendant une transaction, un verrou d'écriture est maintenu sur la valeur de la clé de partition, de sorte que seules les requêtes d'écriture portant l'ID de transaction aboutissent.
La durée de vie maximale d'une transaction est de 60 secondes. Si deux opérations consécutives sont espacées de plus de 60 secondes, la transaction expire et le serveur l'abandonne.
Une seule requête peut utiliser un ID de transaction à la fois. Les opérations simultanées qui partagent le même ID échouent toutes.
Chaque requête d'écriture au sein d'une transaction doit utiliser la même valeur de clé de partition que celle qui a démarré la transaction. Les requêtes de lecture ne sont pas soumises à cette restriction.
Une seule transaction peut écrire jusqu'à 4 Mo de données.
Si une écriture au sein d'une transaction ne spécifie pas de version de colonne (horodatage), le serveur génère l'horodatage au moment de l'écriture, et non au moment de la validation. Les règles correspondent à celles d'une écriture normale.
Lorsqu'une requête
BatchWriteRowporte un ID de transaction, toutes les lignes doivent cibler la table sur laquelle la transaction a été démarrée.Si la transaction ne contient aucune écriture, la validation et l'abandon ont le même effet.
Une requête de lecture ou d'écriture ayant échoué et portant un ID de transaction ne met pas fin à la transaction. Vous pouvez appliquer une politique de nouvelle tentative ou abandonner explicitement la transaction.
Exemples
Lire une ligne au sein d'une transaction
Créez une transaction en lecture seule pour une valeur de clé de partition spécifiée et lisez une ligne.
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);
Écrire par lots plusieurs lignes au sein d'une transaction
Associez l'ID de transaction à une écriture par lots en appelant BatchWriteRowRequest.setTransactionId(txnId). La valeur de la clé de partition de chaque ligne doit correspondre à la valeur utilisée lors du démarrage de la transaction, et la validation applique toutes les lignes de manière atomique.
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);