When using a Cloud Spanner TransactionManager to execute a read/write transaction, TransactionContext#executeUpdate(Statement) and TransactionContext#batchUpdate(Statement) do not handle an aborted transaction correctly. If the following transaction is executed:
DatabaseClient client =
spanner.getDatabaseClient(DatabaseId.of(PROJECT_ID, INSTANCE_ID, DATABASE_ID));
try (TransactionManager manager = client.transactionManager()) {
TransactionContext txn = manager.begin();
while (true) {
try {
...
// Transaction has been aborted by Cloud Spanner before the following statement.
long updateCount = txn.executeUpdate("UPDATE FOO SET BAR=1 WHERE ID=1");
manager.commit();
break;
} catch (AbortedException e) {
Thread.sleep(e.getRetryDelayInMillis() / 1000);
// This line will throw an IllegalStateException with message
// 'resetForRetry can only be called if the previous attempt aborted'
// because the executeUpdate(...) method does not inform the transaction
// manager that the transaction aborted.
txn = manager.resetForRetry();
}
}
}
Related to #4166 and #4939. These issues were fixed, but only when using a TransactionRunner, and not when using a TransactionManager.
When using a Cloud Spanner
TransactionManagerto execute a read/write transaction,TransactionContext#executeUpdate(Statement)andTransactionContext#batchUpdate(Statement)do not handle an aborted transaction correctly. If the following transaction is executed:Related to #4166 and #4939. These issues were fixed, but only when using a
TransactionRunner, and not when using aTransactionManager.