public int prepare() throws StoreAccessException, IllegalStateException, TransactionTimeoutException { try { if (hasTimedOut()) { throw new TransactionTimeoutException();
if (currentContext.hasTimedOut()) { throw new XACacheException("Current XA transaction has timed out");
@Test public void testHasTimedOut() { XATransactionContext<Long, String> xaTransactionContext = new XATransactionContext<>(new TransactionId(new TestXid(0, 0)), null, null, timeSource, timeSource .getTimeMillis() + 30000); assertThat(xaTransactionContext.hasTimedOut(), is(false)); timeSource.advanceTime(30000); assertThat(xaTransactionContext.hasTimedOut(), is(true)); }
@Test public void testTimeoutStart() throws Exception { EhcacheXAResource<Long, String> xaResource = new EhcacheXAResource<>(underlyingStore, journal, xaTransactionContextFactory); when(xaTransactionContextFactory.createTransactionContext(eq(new TransactionId(new TestXid(0, 0))), refEq(underlyingStore), refEq(journal), anyInt())).thenReturn(xaTransactionContext); when(xaTransactionContext.hasTimedOut()).thenReturn(true); try { xaResource.start(new TestXid(0, 0), XAResource.TMNOFLAGS); fail("expected XAException"); } catch (XAException xae) { assertThat(xae.errorCode, is(XAException.XA_RBTIMEOUT)); } verify(xaTransactionContextFactory, times(1)).destroy(eq(new TransactionId(new TestXid(0, 0)))); }
@Test public void testTimeoutEndFail() throws Exception { EhcacheXAResource<Long, String> xaResource = new EhcacheXAResource<>(underlyingStore, journal, xaTransactionContextFactory); when(xaTransactionContextFactory.createTransactionContext(eq(new TransactionId(new TestXid(0, 0))), refEq(underlyingStore), refEq(journal), anyInt())).thenReturn(xaTransactionContext); xaResource.start(new TestXid(0, 0), XAResource.TMNOFLAGS); when(xaTransactionContext.hasTimedOut()).thenReturn(true); when(xaTransactionContextFactory.get(eq(new TransactionId(new TestXid(0, 0))))).thenReturn(xaTransactionContext); try { xaResource.end(new TestXid(0, 0), XAResource.TMFAIL); fail("expected XAException"); } catch (XAException xae) { assertThat(xae.errorCode, is(XAException.XA_RBTIMEOUT)); } verify(xaTransactionContextFactory, times(1)).destroy(eq(new TransactionId(new TestXid(0, 0)))); }
@Test public void testTimeoutEndSuccess() throws Exception { EhcacheXAResource<Long, String> xaResource = new EhcacheXAResource<>(underlyingStore, journal, xaTransactionContextFactory); when(xaTransactionContextFactory.createTransactionContext(eq(new TransactionId(new TestXid(0, 0))), refEq(underlyingStore), refEq(journal), anyInt())).thenReturn(xaTransactionContext); xaResource.start(new TestXid(0, 0), XAResource.TMNOFLAGS); when(xaTransactionContext.hasTimedOut()).thenReturn(true); when(xaTransactionContextFactory.get(eq(new TransactionId(new TestXid(0, 0))))).thenReturn(xaTransactionContext); try { xaResource.end(new TestXid(0, 0), XAResource.TMSUCCESS); fail("expected XAException"); } catch (XAException xae) { assertThat(xae.errorCode, is(XAException.XA_RBTIMEOUT)); } verify(xaTransactionContextFactory, times(1)).destroy(eq(new TransactionId(new TestXid(0, 0)))); }
@Override public void end(Xid xid, int flag) throws XAException { if (flag != XAResource.TMSUCCESS && flag != XAResource.TMFAIL) { throw new EhcacheXAException("End flag not supported : " + xaResourceFlagsToString(flag), XAException.XAER_INVAL); } if (currentXid == null) { throw new EhcacheXAException("Not started on : " + xid, XAException.XAER_PROTO); } TransactionId transactionId = new TransactionId(currentXid); XATransactionContext<K, V> transactionContext = transactionContextFactory.get(transactionId); if (transactionContext == null) { throw new EhcacheXAException("Cannot end unknown XID : " + xid, XAException.XAER_NOTA); } boolean destroyContext = false; if (flag == XAResource.TMFAIL) { destroyContext = true; } currentXid = null; try { if (transactionContext.hasTimedOut()) { destroyContext = true; throw new EhcacheXAException("Transaction timeout for XID : " + xid, XAException.XA_RBTIMEOUT); } } finally { if (destroyContext) { transactionContextFactory.destroy(transactionId); } } }
@Override public void start(Xid xid, int flag) throws XAException { if (flag != XAResource.TMNOFLAGS && flag != XAResource.TMJOIN) { throw new EhcacheXAException("Start flag not supported : " + xaResourceFlagsToString(flag), XAException.XAER_INVAL); } if (currentXid != null) { throw new EhcacheXAException("Already started on : " + xid, XAException.XAER_PROTO); } TransactionId transactionId = new TransactionId(xid); XATransactionContext<K, V> transactionContext = transactionContextFactory.get(transactionId); if (flag == XAResource.TMNOFLAGS) { if (transactionContext == null) { transactionContext = transactionContextFactory.createTransactionContext(transactionId, underlyingStore, journal, transactionTimeoutInSeconds); } else { throw new EhcacheXAException("Cannot start in parallel on two XIDs : starting " + xid, XAException.XAER_RMERR); } } else { if (transactionContext == null) { throw new EhcacheXAException("Cannot join unknown XID : " + xid, XAException.XAER_NOTA); } } if (transactionContext.hasTimedOut()) { transactionContextFactory.destroy(transactionId); throw new EhcacheXAException("Transaction timeout for XID : " + xid, XAException.XA_RBTIMEOUT); } currentXid = xid; }
public int prepare() throws StoreAccessException, IllegalStateException, TransactionTimeoutException { try { if (hasTimedOut()) { throw new TransactionTimeoutException();
if (currentContext.hasTimedOut()) { throw new XACacheException("Current XA transaction has timed out");
@Override public void end(Xid xid, int flag) throws XAException { if (flag != XAResource.TMSUCCESS && flag != XAResource.TMFAIL) { throw new EhcacheXAException("End flag not supported : " + xaResourceFlagsToString(flag), XAException.XAER_INVAL); } if (currentXid == null) { throw new EhcacheXAException("Not started on : " + xid, XAException.XAER_PROTO); } TransactionId transactionId = new TransactionId(currentXid); XATransactionContext<K, V> transactionContext = transactionContextFactory.get(transactionId); if (transactionContext == null) { throw new EhcacheXAException("Cannot end unknown XID : " + xid, XAException.XAER_NOTA); } boolean destroyContext = false; if (flag == XAResource.TMFAIL) { destroyContext = true; } currentXid = null; try { if (transactionContext.hasTimedOut()) { destroyContext = true; throw new EhcacheXAException("Transaction timeout for XID : " + xid, XAException.XA_RBTIMEOUT); } } finally { if (destroyContext) { transactionContextFactory.destroy(transactionId); } } }
@Override public void start(Xid xid, int flag) throws XAException { if (flag != XAResource.TMNOFLAGS && flag != XAResource.TMJOIN) { throw new EhcacheXAException("Start flag not supported : " + xaResourceFlagsToString(flag), XAException.XAER_INVAL); } if (currentXid != null) { throw new EhcacheXAException("Already started on : " + xid, XAException.XAER_PROTO); } TransactionId transactionId = new TransactionId(xid); XATransactionContext<K, V> transactionContext = transactionContextFactory.get(transactionId); if (flag == XAResource.TMNOFLAGS) { if (transactionContext == null) { transactionContext = transactionContextFactory.createTransactionContext(transactionId, underlyingStore, journal, transactionTimeoutInSeconds); } else { throw new EhcacheXAException("Cannot start in parallel on two XIDs : starting " + xid, XAException.XAER_RMERR); } } else { if (transactionContext == null) { throw new EhcacheXAException("Cannot join unknown XID : " + xid, XAException.XAER_NOTA); } } if (transactionContext.hasTimedOut()) { transactionContextFactory.destroy(transactionId); throw new EhcacheXAException("Transaction timeout for XID : " + xid, XAException.XA_RBTIMEOUT); } currentXid = xid; }