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;
 }
Example #2
0
 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;
 }
  private Multimap<Cell, Long> getCellTsPairsToSweep(
      Multimap<Cell, Long> cellTsMappings,
      PeekingIterator<RowResult<Value>> values,
      long sweepTimestamp,
      SweepStrategy sweepStrategy,
      @Output Set<Cell> sentinelsToAdd) {
    Multimap<Cell, Long> cellTsMappingsToSweep = HashMultimap.create();

    Map<Long, Long> startTsToCommitTs = transactionService.get(cellTsMappings.values());
    for (Map.Entry<Cell, Collection<Long>> entry : cellTsMappings.asMap().entrySet()) {
      Cell cell = entry.getKey();
      Collection<Long> timestamps = entry.getValue();
      boolean sweepLastCommitted = isLatestValueEmpty(cell, values);
      Iterable<? extends Long> timestampsToSweep =
          getTimestampsToSweep(
              cell,
              timestamps,
              startTsToCommitTs,
              sentinelsToAdd,
              sweepTimestamp,
              sweepLastCommitted,
              sweepStrategy);
      cellTsMappingsToSweep.putAll(entry.getKey(), timestampsToSweep);
    }
    return cellTsMappingsToSweep;
  }