@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 testTwoNonEndedStartsFails() 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(xaTransactionContextFactory.createTransactionContext(eq(new TransactionId(new TestXid(1, 0))), refEq(underlyingStore), refEq(journal), anyInt())).thenReturn(xaTransactionContext); try { xaResource.start(new TestXid(1, 0), XAResource.TMNOFLAGS); fail("expected XAException"); } catch (XAException xae) { assertThat(xae.errorCode, is(XAException.XAER_PROTO)); } }
@Test public void testStartEndWorks() 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(xaTransactionContextFactory.get(eq(new TransactionId(new TestXid(0, 0))))).thenReturn(xaTransactionContext); xaResource.end(new TestXid(0, 0), XAResource.TMSUCCESS); when(xaTransactionContextFactory.createTransactionContext(eq(new TransactionId(new TestXid(0, 1))), refEq(underlyingStore), refEq(journal), anyInt())).thenReturn(xaTransactionContext); xaResource.start(new TestXid(0, 1), XAResource.TMNOFLAGS); when(xaTransactionContextFactory.get(eq(new TransactionId(new TestXid(0, 1))))).thenReturn(xaTransactionContext); xaResource.end(new TestXid(0, 1), XAResource.TMSUCCESS); }
@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)))); }
@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 testCannotRollbackNonEndedXid() 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); try { xaResource.rollback(new TestXid(0, 0)); fail("expected XAException"); } catch (XAException xae) { assertThat(xae.errorCode, is(XAException.XAER_PROTO)); } }
@Test public void testCannotPrepareNonEndedXid() 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); try { xaResource.prepare(new TestXid(0, 0)); fail("expected XAException"); } catch (XAException xae) { assertThat(xae.errorCode, is(XAException.XAER_PROTO)); } }
@Test public void testCannotCommit1PcNonEndedXid() 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); try { xaResource.commit(new TestXid(0, 0), true); fail("expected XAException"); } catch (XAException xae) { assertThat(xae.errorCode, is(XAException.XAER_PROTO)); } }
@Test public void testJoinWorks() 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(xaTransactionContextFactory.get(eq(new TransactionId(new TestXid(0, 0))))).thenReturn(xaTransactionContext); xaResource.end(new TestXid(0, 0), XAResource.TMSUCCESS); xaResource.start(new TestXid(0, 0), XAResource.TMJOIN); xaResource.end(new TestXid(0, 0), XAResource.TMSUCCESS); }
@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; }
@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; }