in src/main/java/com/amazonaws/services/dynamodbv2/transactions/ReadCommittedIsolationHandlerImpl.java [133:178]
protected Map<String, AttributeValue> handleItem(
final Map<String, AttributeValue> item,
final String tableName,
final int numRetries) {
GetItemRequest request = null; // only create if necessary
for (int i = 0; i <= numRetries; i++) {
final Map<String, AttributeValue> currentItem;
if (i == 0) {
currentItem = item;
} else {
if (request == null) {
request = createGetItemRequest(tableName, item);
}
currentItem = txManager.getClient().getItem(request).getItem();
}
// 1. Return the item if it isn't locked (or if it's locked, but not applied yet)
try {
return checkItemCommitted(currentItem);
} catch (TransactionException e1) {
try {
// 2. Load the locking transaction
Transaction lockingTx = loadTransaction(e1.getTxId());
/*
* 3. See if the locking transaction has been committed. If so, return the item. This is valid because you cannot
* write to an item multiple times in the same transaction. Otherwise it would expose intermediate state.
*/
if (TransactionItem.State.COMMITTED.equals(lockingTx.getTxItem().getState())) {
return currentItem;
}
// 4. Try to get a previously committed version of the item
if (request == null) {
request = createGetItemRequest(tableName, item);
}
return getOldCommittedItem(lockingTx, tableName, request.getKey());
} catch (UnknownCompletedTransactionException e2) {
LOG.debug("Could not find item image. Transaction must have already completed.", e2);
} catch (TransactionNotFoundException e2) {
LOG.debug("Unable to find locking transaction. Transaction must have already completed.", e2);
}
}
}
throw new TransactionException(null, "Ran out of attempts to get a committed image of the item");
}