protected SoftLock<V> copyAfterDeserialization(Serializer<V> valueSerializer, SoftLock<V> serializedSoftLock) throws ClassNotFoundException { V oldValue = null; if (serializedSoftLock.oldValueSerialized != null) { oldValue = valueSerializer.read(ByteBuffer.wrap(serializedSoftLock.oldValueSerialized)); } XAValueHolder<V> newValueHolder = null; if (this.newValueHolder != null) { newValueHolder = this.newValueHolder.copyAfterDeserialization(valueSerializer); } return new SoftLock<>(transactionId, oldValue, newValueHolder); }
protected SoftLock<V> copyForSerialization(Serializer<V> valueSerializer) { ByteBuffer serializedOldValue = null; if (oldValue != null) { serializedOldValue = valueSerializer.serialize(oldValue); } XAValueHolder<V> serializedXaValueHolder = null; if (newValueHolder != null) { serializedXaValueHolder = newValueHolder.copyForSerialization(valueSerializer); } return new SoftLock<>(transactionId, serializedOldValue, serializedXaValueHolder); }
SoftLock<V> oldSoftLock = oldValue == null ? null : new SoftLock<>(null, oldValue, null); SoftLock<V> newSoftLock = new SoftLock<>(transactionId, oldValue, entry.getValue().getNewValueHolder()); if (oldSoftLock != null) { boolean replaced = replaceInUnderlyingStore(entry.getKey(), oldSoftLock, newSoftLock);
SoftLock<V> preparedSoftLock = getFromUnderlyingStore(key); V oldValue = preparedSoftLock == null ? null : preparedSoftLock.getOldValue(); SoftLock<V> definitiveSoftLock = oldValue == null ? null : new SoftLock<>(null, oldValue, null);
@Override public SoftLock<T> copyForRead(SoftLock<T> obj) { T oldValue = valueCopier.copyForRead(obj.getOldValue()); XAValueHolder<T> valueHolder = obj.getNewValueHolder(); XAValueHolder<T> newValueHolder = valueHolder == null ? null : new XAValueHolder<>(valueHolder, valueCopier.copyForRead(valueHolder .get())); return new SoftLock<>(obj.getTransactionId(), oldValue, newValueHolder); }
@Override public SoftLock<T> copyForWrite(SoftLock<T> obj) { T oldValue = valueCopier.copyForWrite(obj.getOldValue()); XAValueHolder<T> valueHolder = obj.getNewValueHolder(); XAValueHolder<T> newValueHolder = valueHolder == null ? null : new XAValueHolder<>(valueHolder, valueCopier.copyForWrite(valueHolder .get())); return new SoftLock<>(obj.getTransactionId(), oldValue, newValueHolder); }
SoftLock<V> preparedSoftLock = getFromUnderlyingStore(key); XAValueHolder<V> newValueHolder = preparedSoftLock == null ? null : preparedSoftLock.getNewValueHolder(); SoftLock<V> definitiveSoftLock = newValueHolder == null ? null : new SoftLock<>(null, newValueHolder.get(), null);
@Test @SuppressWarnings("unchecked") public void testPrepareConflictsEvicts() throws Exception { XATransactionContext<Long, String> xaTransactionContext = getXaTransactionContext(); xaTransactionContext.addCommand(1L, new StorePutCommand<>("one", new XAValueHolder<>("un", timeSource.getTimeMillis()))); xaTransactionContext.addCommand(2L, new StoreRemoveCommand<>("two")); when(underlyingStore.replace(any(Long.class), any(SoftLock.class), any(SoftLock.class))).thenReturn(ReplaceStatus.MISS_NOT_PRESENT); xaTransactionContext.prepare(); verify(underlyingStore).replace(eq(1L), eq(new SoftLock<>(null, "one", null)), eq(new SoftLock<>(new TransactionId(new TestXid(0, 0)), "one", new XAValueHolder<>("un", timeSource .getTimeMillis())))); verify(underlyingStore).remove(1L); verify(underlyingStore).replace(eq(2L), eq(new SoftLock<>(null, "two", null)), eq(new SoftLock<>(new TransactionId(new TestXid(0, 0)), "two", null))); verify(underlyingStore).remove(2L); }
@Override public SoftLock<String> get() { return new SoftLock<>(new TransactionId(new TestXid(0, 0)), "old1", new XAValueHolder<>("new1", timeSource .getTimeMillis())); @Override public SoftLock<String> get() { return new SoftLock<>(new TransactionId(new TestXid(0, 0)), "old2", null); verify(underlyingStore, times(1)).replace(eq(1L), eq(new SoftLock<>(new TransactionId(new TestXid(0, 0)), "old1", new XAValueHolder<>("new1", timeSource .getTimeMillis()))), eq(new SoftLock<>(null, "old1", null))); verify(underlyingStore, times(1)).remove(eq(1L)); verify(underlyingStore, times(1)).replace(eq(2L), eq(new SoftLock<>(new TransactionId(new TestXid(0, 0)), "old2", null)), eq(new SoftLock<>(null, "old2", null))); verify(underlyingStore, times(1)).remove(eq(2L));
@Test @SuppressWarnings("unchecked") public void testRollbackPhase2() throws Exception { XATransactionContext<Long, String> xaTransactionContext = getXaTransactionContext(); xaTransactionContext.addCommand(1L, new StorePutCommand<>("one", new XAValueHolder<>("un", timeSource.getTimeMillis()))); xaTransactionContext.addCommand(2L, new StoreRemoveCommand<>("two")); when(journal.isInDoubt(eq(new TransactionId(new TestXid(0, 0))))).thenReturn(true); when(journal.getInDoubtKeys(eq(new TransactionId(new TestXid(0, 0))))).thenReturn(Arrays.asList(1L, 2L)); when(underlyingStore.get(1L)).thenReturn(new AbstractValueHolder<SoftLock<String>>(-1, -1) { @Override public SoftLock<String> get() { return new SoftLock<>(new TransactionId(new TestXid(0, 0)), "one", new XAValueHolder<>("un", timeSource.getTimeMillis())); } }); when(underlyingStore.get(2L)).thenReturn(new AbstractValueHolder<SoftLock<String>>(-1, -1) { @Override public SoftLock<String> get() { return new SoftLock<>(new TransactionId(new TestXid(0, 0)), "two", null); } }); when(underlyingStore.replace(any(Long.class), any(SoftLock.class), any(SoftLock.class))).thenReturn(ReplaceStatus.HIT); xaTransactionContext.rollback(false); verify(underlyingStore, times(1)).get(1L); verify(underlyingStore, times(1)).replace(eq(1L), eq(new SoftLock<>(new TransactionId(new TestXid(0, 0)), "one", new XAValueHolder<>("un", timeSource .getTimeMillis()))), eq(new SoftLock<>(null, "one", null))); verify(underlyingStore, times(1)).get(2L); verify(underlyingStore, times(1)).replace(eq(2L), eq(new SoftLock<>(new TransactionId(new TestXid(0, 0)), "two", null)), eq(new SoftLock<>(null, "two", null))); }
@Test @SuppressWarnings("unchecked") public void testCommitConflictsEvicts() throws Exception { XATransactionContext<Long, String> xaTransactionContext = getXaTransactionContext(); when(journal.isInDoubt(eq(new TransactionId(new TestXid(0, 0))))).thenReturn(true); when(journal.getInDoubtKeys(eq(new TransactionId(new TestXid(0, 0))))).thenReturn(Arrays.asList(1L, 2L)); when(underlyingStore.get(eq(1L))).thenReturn(new AbstractValueHolder<SoftLock<String>>(-1, -1) { @Override public SoftLock<String> get() { return new SoftLock<>(new TransactionId(new TestXid(0, 0)), "old1", new XAValueHolder<>("new1", timeSource .getTimeMillis())); } }); when(underlyingStore.get(eq(2L))).thenReturn(new AbstractValueHolder<SoftLock<String>>(-1, -1) { @Override public SoftLock<String> get() { return new SoftLock<>(new TransactionId(new TestXid(0, 0)), "old2", null); } }); when(underlyingStore.replace(any(Long.class), any(SoftLock.class), any(SoftLock.class))).thenReturn(ReplaceStatus.MISS_NOT_PRESENT); when(underlyingStore.remove(any(Long.class), any(SoftLock.class))).thenReturn(RemoveStatus.KEY_MISSING); xaTransactionContext.commit(false); verify(underlyingStore, times(1)).replace(eq(1L), eq(new SoftLock<>(new TransactionId(new TestXid(0, 0)), "old1", new XAValueHolder<>("new1", timeSource .getTimeMillis()))), eq(new SoftLock<>(null, "new1", null))); verify(underlyingStore, times(1)).remove(eq(1L)); verify(underlyingStore, times(1)).remove(eq(2L), eq(new SoftLock<>(new TransactionId(new TestXid(0, 0)), "old2", null))); verify(underlyingStore, times(1)).remove(eq(2L)); }
when(mockValueHolder.get()).thenReturn(new SoftLock<>(null, "two", null)); when(underlyingStore.get(eq(2L))).thenReturn(mockValueHolder); when(underlyingStore.replace(eq(2L), eq(new SoftLock<>(null, "two", null)), eq(new SoftLock<>(new TransactionId(new TestXid(0, 0)), "two", null)))).thenReturn(ReplaceStatus.HIT); verify(underlyingStore, times(1)).putIfAbsent(eq(1L), eq(new SoftLock<>(new TransactionId(new TestXid(0, 0)), null, new XAValueHolder<>("un", timeSource .getTimeMillis()))), any(Consumer.class)); verify(underlyingStore, times(0)).get(2L); verify(underlyingStore, times(1)).replace(eq(2L), eq(new SoftLock<>(null, "two", null)), eq(new SoftLock<>(new TransactionId(new TestXid(0, 0)), "two", null))); verify(underlyingStore, times(0)).get(3L); verify(underlyingStore, times(1)).remove(eq(3L));
when(mockValueHolder1.get()).thenReturn(new SoftLock<>(new TransactionId(new TestXid(0, 0)), "one", new XAValueHolder<>("un", timeSource .getTimeMillis()))); when(underlyingStore.get(eq(1L))).thenReturn(mockValueHolder1); Store.ValueHolder<SoftLock<String>> mockValueHolder2 = mock(Store.ValueHolder.class); when(mockValueHolder2.get()).thenReturn(new SoftLock<>(new TransactionId(new TestXid(0, 0)), "two", null)); when(underlyingStore.get(eq(2L))).thenReturn(mockValueHolder2); Store.ValueHolder<SoftLock<String>> mockValueHolder3 = mock(Store.ValueHolder.class); when(mockValueHolder3.get()).thenReturn(new SoftLock<>(new TransactionId(new TestXid(0, 0)), "three", null)); when(underlyingStore.get(eq(3L))).thenReturn(mockValueHolder3); verify(underlyingStore, times(1)).replace(eq(1L), eq(new SoftLock<>(new TransactionId(new TestXid(0, 0)), "one", new XAValueHolder<>("un", timeSource .getTimeMillis()))), eq(new SoftLock<>(null, "un", null))); verify(underlyingStore, times(1)).get(2L); verify(underlyingStore, times(1)).remove(eq(2L), eq(new SoftLock<>(new TransactionId(new TestXid(0, 0)), "two", null))); verify(underlyingStore, times(1)).get(3L); verify(underlyingStore, times(1)).remove(eq(3L));
when(mockValueHolder.get()).thenReturn(new SoftLock<>(null, "two", null)); when(underlyingStore.get(eq(2L))).thenReturn(mockValueHolder); AtomicReference<SoftLock<Object>> softLock2Ref = new AtomicReference<>(new SoftLock<>(null, "two", null)); when(underlyingStore.get(eq(2L))).then(invocation -> softLock2Ref.get() == null ? null : new AbstractValueHolder<Object>(-1, -1) { @Override verify(journal, times(1)).saveInDoubt(eq(new TransactionId(new TestXid(0, 0))), any(Collection.class)); verify(underlyingStore, times(1)).putIfAbsent(eq(1L), eq(new SoftLock<>(new TransactionId(new TestXid(0, 0)), null, new XAValueHolder<>("un", timeSource .getTimeMillis()))), any(Consumer.class)); verify(underlyingStore, times(1)).replace(eq(2L), eq(new SoftLock<>(null, "two", null)), eq(new SoftLock<>(new TransactionId(new TestXid(0, 0)), "two", null))); verify(underlyingStore, times(1)).remove(eq(3L)); verify(underlyingStore, times(1)).replace(eq(1L), eq(new SoftLock<>(new TransactionId(new TestXid(0, 0)), null, new XAValueHolder<>("un", timeSource .getTimeMillis()))), eq(new SoftLock<>(null, "un", null))); verify(underlyingStore, times(1)).get(2L); verify(underlyingStore, times(1)).remove(eq(2L), eq(new SoftLock<>(new TransactionId(new TestXid(0, 0)), "two", null))); verify(underlyingStore, times(1)).get(3L); verify(underlyingStore, times(1)).remove(eq(3L));
@Test public void testCommitNotPreparedInFlightThrows() throws Exception { XATransactionContext<Long, String> xaTransactionContext = getXaTransactionContext(); xaTransactionContext.addCommand(1L, new StorePutCommand<>("one", new XAValueHolder<>("un", timeSource.getTimeMillis()))); xaTransactionContext.addCommand(2L, new StorePutCommand<>("two", new XAValueHolder<>("deux", timeSource.getTimeMillis()))); @SuppressWarnings("unchecked") Store.ValueHolder<SoftLock<String>> mockValueHolder = mock(Store.ValueHolder.class); when(mockValueHolder.get()).thenReturn(new SoftLock<>(null, "two", null)); when(underlyingStore.get(eq(2L))).thenReturn(mockValueHolder); try { xaTransactionContext.commit(false); fail("expected IllegalArgumentException"); } catch (IllegalArgumentException ise) { // expected } }
protected SoftLock<V> copyAfterDeserialization(Serializer<V> valueSerializer, SoftLock<V> serializedSoftLock) throws ClassNotFoundException { V oldValue = null; if (serializedSoftLock.oldValueSerialized != null) { oldValue = valueSerializer.read(ByteBuffer.wrap(serializedSoftLock.oldValueSerialized)); } XAValueHolder<V> newValueHolder = null; if (this.newValueHolder != null) { newValueHolder = this.newValueHolder.copyAfterDeserialization(valueSerializer); } return new SoftLock<>(transactionId, oldValue, newValueHolder); }
protected SoftLock<V> copyForSerialization(Serializer<V> valueSerializer) { ByteBuffer serializedOldValue = null; if (oldValue != null) { serializedOldValue = valueSerializer.serialize(oldValue); } XAValueHolder<V> serializedXaValueHolder = null; if (newValueHolder != null) { serializedXaValueHolder = newValueHolder.copyForSerialization(valueSerializer); } return new SoftLock<>(transactionId, serializedOldValue, serializedXaValueHolder); }
SoftLock<V> oldSoftLock = oldValue == null ? null : new SoftLock<>(null, oldValue, null); SoftLock<V> newSoftLock = new SoftLock<>(transactionId, oldValue, entry.getValue().getNewValueHolder()); if (oldSoftLock != null) { boolean replaced = replaceInUnderlyingStore(entry.getKey(), oldSoftLock, newSoftLock);
@Override public SoftLock<T> copyForRead(SoftLock<T> obj) { T oldValue = valueCopier.copyForRead(obj.getOldValue()); XAValueHolder<T> valueHolder = obj.getNewValueHolder(); XAValueHolder<T> newValueHolder = valueHolder == null ? null : new XAValueHolder<>(valueHolder, valueCopier.copyForRead(valueHolder .get())); return new SoftLock<>(obj.getTransactionId(), oldValue, newValueHolder); }
@Override public SoftLock<T> copyForWrite(SoftLock<T> obj) { T oldValue = valueCopier.copyForWrite(obj.getOldValue()); XAValueHolder<T> valueHolder = obj.getNewValueHolder(); XAValueHolder<T> newValueHolder = valueHolder == null ? null : new XAValueHolder<>(valueHolder, valueCopier.copyForWrite(valueHolder .get())); return new SoftLock<>(obj.getTransactionId(), oldValue, newValueHolder); }