@Test public void testCannotRollbackUnknownXidInFlight() throws Exception { EhcacheXAResource<Long, String> xaResource = new EhcacheXAResource<>(underlyingStore, journal, xaTransactionContextFactory); when(xaTransactionContextFactory.get(eq(new TransactionId(new TestXid(0, 0))))).thenReturn(xaTransactionContext); doThrow(IllegalStateException.class).when(xaTransactionContext).rollback(eq(false)); try { xaResource.rollback(new TestXid(0, 0)); fail("expected XAException"); } catch (XAException xae) { assertThat(xae.errorCode, is(XAException.XAER_NOTA)); } }
when(underlyingStore.remove(any(Long.class), any(SoftLock.class))).thenReturn(RemoveStatus.KEY_MISSING); xaTransactionContext.rollback(false);
@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 public void testRollbackPhase1() throws Exception { XATransactionContext<Long, String> xaTransactionContext = getXaTransactionContext(); xaTransactionContext.addCommand(1L, new StorePutCommand<>("one", new XAValueHolder<>("un", timeSource.getTimeMillis()))); xaTransactionContext.addCommand(2L, new StoreRemoveCommand<>("two")); xaTransactionContext.rollback(false); verifyNoMoreInteractions(underlyingStore); }
@Override public void rollback(Xid xid) throws XAException { if (currentXid != null) { throw new EhcacheXAException("Cannot rollback a non-ended start on : " + xid, XAException.XAER_PROTO); } TransactionId transactionId = new TransactionId(xid); XATransactionContext<K, V> transactionContext = transactionContextFactory.get(transactionId); try { XATransactionContext<K, V> rollbackContext = transactionContext; if (rollbackContext == null) { // recovery rollback rollbackContext = new XATransactionContext<>(new TransactionId(new SerializableXid(xid)), underlyingStore, journal, null, 0L); } rollbackContext.rollback(transactionContext == null); } catch (IllegalStateException ise) { throw new EhcacheXAException("Cannot rollback unknown XID : " + xid, XAException.XAER_NOTA); } catch (StoreAccessException cae) { throw new EhcacheXAException("Cannot rollback XID : " + xid, XAException.XAER_RMERR, cae); } finally { if (transactionContext != null) { transactionContextFactory.destroy(transactionId); } } }
@Override public void rollback(Xid xid) throws XAException { if (currentXid != null) { throw new EhcacheXAException("Cannot rollback a non-ended start on : " + xid, XAException.XAER_PROTO); } TransactionId transactionId = new TransactionId(xid); XATransactionContext<K, V> transactionContext = transactionContextFactory.get(transactionId); try { XATransactionContext<K, V> rollbackContext = transactionContext; if (rollbackContext == null) { // recovery rollback rollbackContext = new XATransactionContext<>(new TransactionId(new SerializableXid(xid)), underlyingStore, journal, null, 0L); } rollbackContext.rollback(transactionContext == null); } catch (IllegalStateException ise) { throw new EhcacheXAException("Cannot rollback unknown XID : " + xid, XAException.XAER_NOTA); } catch (StoreAccessException cae) { throw new EhcacheXAException("Cannot rollback XID : " + xid, XAException.XAER_RMERR, cae); } finally { if (transactionContext != null) { transactionContextFactory.destroy(transactionId); } } }