protected void throwIfWriteAlreadyCommitted(TableReference tableRef, Map<Cell, byte[]> writes, ConflictHandler conflictHandler, LockToken commitLocksToken, TransactionService transactionService) throws TransactionConflictException { if (writes.isEmpty() || !conflictHandler.checkWriteWriteConflicts()) { return; } Set<CellConflict> spanningWrites = Sets.newHashSet(); Set<CellConflict> dominatingWrites = Sets.newHashSet(); Map<Cell, Long> keysToLoad = Maps.asMap(writes.keySet(), Functions.constant(Long.MAX_VALUE)); while (!keysToLoad.isEmpty()) { keysToLoad = detectWriteAlreadyCommittedInternal( tableRef, keysToLoad, spanningWrites, dominatingWrites, transactionService); } if (conflictHandler == ConflictHandler.RETRY_ON_VALUE_CHANGED) { throwIfValueChangedConflict(tableRef, writes, spanningWrites, dominatingWrites, commitLocksToken); } else { if (!spanningWrites.isEmpty() || !dominatingWrites.isEmpty()) { transactionOutcomeMetrics.markWriteWriteConflict(tableRef); throw TransactionConflictException.create(tableRef, getStartTimestamp(), spanningWrites, dominatingWrites, System.currentTimeMillis() - timeCreated); } } }
Predicates.in(conflictingCells), CellConflict.getCellFunction()); transactionOutcomeMetrics.markWriteWriteConflict(table); throw TransactionConflictException.create(table, getStartTimestamp(),
@Test public void conflictsInUnsafeTablesAreTrackedWithPlaceholder() { transactionOutcomeMetrics.markWriteWriteConflict(UNSAFE_REFERENCE_1); assertThat(transactionOutcomeMetrics).hasPlaceholderWriteWriteConflicts(1); }
@Test public void conflictsInUnsafeTablesAreNotIncludedAsTags() { transactionOutcomeMetrics.markWriteWriteConflict(UNSAFE_REFERENCE_1); transactionOutcomeMetrics.markReadWriteConflict(UNSAFE_REFERENCE_2); assertThat(transactionOutcomeMetrics) .hasNoKnowledgeOf(UNSAFE_REFERENCE_1) .hasNoKnowledgeOf(UNSAFE_REFERENCE_2); }
@Test public void tableReferencesIncludedAsTagIfSafe() { transactionOutcomeMetrics.markReadWriteConflict(SAFE_REFERENCE_1); transactionOutcomeMetrics.markReadWriteConflict(SAFE_REFERENCE_1); transactionOutcomeMetrics.markWriteWriteConflict(SAFE_REFERENCE_1); assertThat(transactionOutcomeMetrics) .hasNamedReadWriteConflicts(SAFE_REFERENCE_1, 2) .hasNamedWriteWriteConflicts(SAFE_REFERENCE_1, 1); }
protected void throwIfWriteAlreadyCommitted(TableReference tableRef, Map<Cell, byte[]> writes, ConflictHandler conflictHandler, LockToken commitLocksToken, TransactionService transactionService) throws TransactionConflictException { if (writes.isEmpty() || !conflictHandler.checkWriteWriteConflicts()) { return; } Set<CellConflict> spanningWrites = Sets.newHashSet(); Set<CellConflict> dominatingWrites = Sets.newHashSet(); Map<Cell, Long> keysToLoad = Maps.asMap(writes.keySet(), Functions.constant(Long.MAX_VALUE)); while (!keysToLoad.isEmpty()) { keysToLoad = detectWriteAlreadyCommittedInternal( tableRef, keysToLoad, spanningWrites, dominatingWrites, transactionService); } if (conflictHandler == ConflictHandler.RETRY_ON_VALUE_CHANGED) { throwIfValueChangedConflict(tableRef, writes, spanningWrites, dominatingWrites, commitLocksToken); } else { if (!spanningWrites.isEmpty() || !dominatingWrites.isEmpty()) { transactionOutcomeMetrics.markWriteWriteConflict(tableRef); throw TransactionConflictException.create(tableRef, getStartTimestamp(), spanningWrites, dominatingWrites, System.currentTimeMillis() - timeCreated); } } }
Predicates.in(conflictingCells), CellConflict.getCellFunction()); transactionOutcomeMetrics.markWriteWriteConflict(table); throw TransactionConflictException.create(table, getStartTimestamp(),