Vassil Lunchev
Vassil Lunchev

Reputation: 159

How to use transactions in Cloud Datastore

I want to use Datastore from Cloud Compute through Java and I am following Getting started with Google Cloud Datastore.

My use case is quite standard - read one entity (lookup), modify it and save the new version. I want to do it in a transaction so that if two processes do this, the second one won't overwrite the changes made by the first one.

I managed to issue a transaction and it works. However I don't know what would happen if the transaction fails:

Upvotes: 1

Views: 2236

Answers (1)

Ed Davisson
Ed Davisson

Reputation: 2927

How to identify a failed transaction? Probably a DatastoreException with some specific code or name will be thrown?

Your code should always ensure that a transaction is either successfully committed or rolled back. Here's an example:

// Begin the transaction.
BeginTransactionRequest begin = BeginTransactionRequest.newBuilder()
    .build();
ByteString txn = datastore.beginTransaction(begin)
  .getTransaction();
try {
  // Zero or more transactional lookup()s or runQuerys().
  // ...

  // Followed by a commit().
  CommitRequest commit = CommitRequest.newBuilder()
      .setTransaction(txn)
      .addMutation(...)
      .build();
  datastore.commit(commit);
} catch (Exception e) {
  // If a transactional operation fails for any reason,
  // attempt to roll back. 
  RollbackRequest rollback = RollbackRequest.newBuilder()
      .setTransaction(txn);
      .build();
  try {
    datastore.rollback(rollback);
  } catch (DatastoreException de) {
    // Rollback may fail due to a transient error or if
    // the transaction was already committed.
  }
  // Propagate original exception.
  throw e;
}

An exception might be thrown by commit() or by another lookup() or runQuery() call inside the try block. In each case, it's important to clean up the transaction.

Should I issue a rollback explicitly? Can I assume that if a transaction fails, nothing from it will be written?

Unless you're sure that the commit() succeeded, you should explicitly issue a rollback() request. However, a failed commit() does not necessarily mean that no data was written. See the note on this page.

Should I retry?

You can retry using exponential backoff. However, frequent transaction failures may indicate that you are attempting to write too frequently to an entity group.

Is there any documentation on that?

https://cloud.google.com/datastore/docs/concepts/transactions

Upvotes: 2

Related Questions