private long ensureCommitTimestampExists( Long startTs, @Modified Map<Long, Long> startTsToCommitTs) { Long commitTs = startTsToCommitTs.get(startTs); if (commitTs == null) { // Roll back this transaction (note that rolling back arbitrary transactions // can never cause correctness issues, only liveness issues) try { // TODO: carrino: use the batched version of putUnlessExists when it is available. transactionService.putUnlessExists(startTs, TransactionConstants.FAILED_COMMIT_TS); } catch (KeyAlreadyExistsException e) { String msg = "Could not roll back transaction with start timestamp " + startTs + "; either" + " it was already rolled back (by a different transaction), or it committed successfully" + " before we could roll it back."; log.error( "This isn't a bug but it should be very infrequent. " + msg, new TransactionFailedRetriableException(msg, e)); } commitTs = transactionService.get(startTs); Validate.notNull(commitTs); startTsToCommitTs.put(startTs, commitTs); } return commitTs; }
private long getCommitTimestampRollBackIfNecessary( long startTimestamp, Multimap<String, Cell> tableNameToCell) { Long commitTimestamp = transactionService.get(startTimestamp); if (commitTimestamp == null) { // Roll back this transaction (note that rolling back arbitrary transactions // can never cause correctness issues, only liveness issues) try { transactionService.putUnlessExists(startTimestamp, TransactionConstants.FAILED_COMMIT_TS); } catch (KeyAlreadyExistsException e) { String msg = "Could not roll back transaction with start timestamp " + startTimestamp + "; either" + " it was already rolled back (by a different transaction), or it committed successfully" + " before we could roll it back."; log.error( "This isn't a bug but it should be very infrequent. " + msg, new TransactionFailedRetriableException(msg, e)); } commitTimestamp = transactionService.get(startTimestamp); } if (commitTimestamp == null) { throw new RuntimeException( "expected commit timestamp to be non-null for startTs: " + startTimestamp); } if (commitTimestamp == TransactionConstants.FAILED_COMMIT_TS) { for (String table : tableNameToCell.keySet()) { Map<Cell, Long> toDelete = Maps2.createConstantValueMap(tableNameToCell.get(table), startTimestamp); keyValueService.delete(table, Multimaps.forMap(toDelete)); } } return commitTimestamp; }