@Theory public void shouldAcquireRowAndCellLockIfRequiresBoth(ConflictHandler conflictHandler) { Assume.assumeTrue(conflictHandler.lockCellsForConflicts() && conflictHandler.lockRowsForConflicts()); PreCommitCondition cellAndRowLockAcquired = (ignored) -> { LockResponse cellLockResponse = acquireCellLock(ROW, COLUMN); LockResponse rowLockResponse = acquireRowLock(ROW); assertFalse(cellLockResponse.wasSuccessful()); assertFalse(rowLockResponse.wasSuccessful()); }; commitWriteWith(cellAndRowLockAcquired, conflictHandler); }
public static TableMetadataPersistence.TableConflictHandler persistToProto(ConflictHandler conflictHandler) { return TableMetadataPersistence.TableConflictHandler.valueOf(conflictHandler.name()); }
boolean isSerializableTable(TableReference table) { // If the metadata is null, we assume that the conflict handler is not SERIALIZABLE. // In that case the transaction will fail on commit if it has writes. ConflictHandler conflictHandler = conflictDetectionManager.get(table); return conflictHandler.checkReadWriteConflicts(); }
@Theory public void shouldNotAcquireCellLockIfDoesNotLockAtCellLevel(ConflictHandler conflictHandler) { Assume.assumeFalse(conflictHandler.lockCellsForConflicts()); PreCommitCondition canAcquireCellLock = (ignored) -> { LockResponse response = acquireCellLock(ROW, COLUMN); //current lock implementation allows you to get a cell lock on a row that is already locked assertTrue(response.wasSuccessful()); }; commitWriteWith(canAcquireCellLock, conflictHandler); }
@Theory public void shouldAcquireRowLockIfLocksAtRowLevel(ConflictHandler conflictHandler) { Assume.assumeTrue(conflictHandler.lockRowsForConflicts()); PreCommitCondition rowLocksAcquired = (ignored) -> { LockResponse response = acquireRowLock(ROW); assertFalse(response.wasSuccessful()); }; commitWriteWith(rowLocksAcquired, conflictHandler); }
public static ConflictHandler hydrateFromProto(TableMetadataPersistence.TableConflictHandler conflictHandler) { return ConflictHandler.valueOf(conflictHandler.name()); } }
@Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((cachePriority == null) ? 0 : cachePriority.hashCode()); result = prime * result + ((columns == null) ? 0 : columns.hashCode()); result = prime * result + ((conflictHandler == null) ? 0 : conflictHandler.hashCode()); result = prime * result + (rangeScanAllowed ? 1231 : 1237); result = prime * result + ((rowMetadata == null) ? 0 : rowMetadata.hashCode()); result = prime * result + (rangeScanAllowed ? 0 : 1); result = prime * result + explicitCompressionBlockSizeKB; result = prime * result + (negativeLookups ? 0 : 1); result = prime * result + sweepStrategy.hashCode(); result = prime * result + (appendHeavyAndReadLight ? 0 : 1); result = prime * result + nameLogSafety.hashCode(); // Nonnull, because it has a default value return result; }
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); } } }
Validate.isTrue(ConflictHandler.RETRY_ON_WRITE_WRITE.equals(tableMetadata.conflictHandler), "Nonadditive indexes require write-write conflicts on their tables");
@Theory public void shouldAcquireCellLockIfLocksAtCellLevel(ConflictHandler conflictHandler) { Assume.assumeTrue(conflictHandler.lockCellsForConflicts()); PreCommitCondition cellLocksAcquired = (ignored) -> { LockResponse response = acquireCellLock(ROW, COLUMN); assertFalse(response.wasSuccessful()); }; commitWriteWith(cellLocksAcquired, conflictHandler); }
@Theory public void shouldNotAcquireRowLockIfDoesNotLockAtRowLevel(ConflictHandler conflictHandler) { Assume.assumeFalse(conflictHandler.lockRowsForConflicts()); PreCommitCondition canAcquireRowLock = (ignored) -> { LockResponse response = acquireRowLock(ROW); assertTrue(response.wasSuccessful()); }; commitWriteWith(canAcquireRowLock, conflictHandler); }
public static ConflictHandler hydrateFromProto(TableMetadataPersistence.TableConflictHandler conflictHandler) { return ConflictHandler.valueOf(conflictHandler.name()); } }
@Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((cachePriority == null) ? 0 : cachePriority.hashCode()); result = prime * result + ((columns == null) ? 0 : columns.hashCode()); result = prime * result + ((conflictHandler == null) ? 0 : conflictHandler.hashCode()); result = prime * result + (rangeScanAllowed ? 1231 : 1237); result = prime * result + ((rowMetadata == null) ? 0 : rowMetadata.hashCode()); result = prime * result + (rangeScanAllowed ? 0 : 1); result = prime * result + explicitCompressionBlockSizeKB; result = prime * result + (negativeLookups ? 0 : 1); result = prime * result + sweepStrategy.hashCode(); result = prime * result + (appendHeavyAndReadLight ? 0 : 1); result = prime * result + nameLogSafety.hashCode(); // Nonnull, because it has a default value return result; }
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); } } }
Validate.isTrue(ConflictHandler.RETRY_ON_WRITE_WRITE.equals(tableMetadata.conflictHandler), "Nonadditive indexes require write-write conflicts on their tables");
if (conflictHandler.lockCellsForConflicts()) { for (Cell cell : getLocalWrites(tableRef).keySet()) { result.add( if (conflictHandler.lockRowsForConflicts()) { Cell lastCell = null; for (Cell cell : getLocalWrites(tableRef).keySet()) {
@Theory public void canAcquireLockOnMultipleCellsOnSameRow(ConflictHandler conflictHandler) { Assume.assumeTrue(conflictHandler.lockCellsForConflicts()); PreCommitCondition canAcquireLockOnDifferentCell = (ignored) -> { LockResponse response = acquireCellLock(ROW, OTHER_COLUMN); assertTrue(response.wasSuccessful()); }; commitWriteWith(canAcquireLockOnDifferentCell, conflictHandler); }
@Theory public void shouldNotAcquireRowLockIfDoesNotLockAtRowLevel(ConflictHandler conflictHandler) { Assume.assumeFalse(conflictHandler.lockRowsForConflicts()); PreCommitCondition canAcquireRowLock = (ignored) -> { LockResponse response = acquireRowLock(ROW); assertTrue(response.wasSuccessful()); }; commitWriteWith(canAcquireRowLock, conflictHandler); }
jgen.writeStringField("conflictHandler", value.getConflictHandler().name()); jgen.writeStringField("cachePriority", value.getCachePriority().name()); jgen.writeBooleanField("rangeScanAllowed", value.isRangeScanAllowed());
boolean isSerializableTable(TableReference table) { // If the metadata is null, we assume that the conflict handler is not SERIALIZABLE. // In that case the transaction will fail on commit if it has writes. ConflictHandler conflictHandler = conflictDetectionManager.get(table); return conflictHandler.checkReadWriteConflicts(); }