Question

I am running simple test case based on one of the Infinispan unit tests. In my test I expect to receive CacheException when replication timeouts in my cluster.

I use pessimistic transaction locking and exception is not thrown in this case for some reason. If I comment pessimistic locking I get exception as expected.

@Test(groups = "functional", testName = "replication.ReplicationExceptionTest")
public class ReplicationExceptionTest extends MultipleCacheManagersTest {

    protected void createCacheManagers() {
        ConfigurationBuilder configuration = getDefaultClusteredCacheConfig(CacheMode.REPL_SYNC, true);
        configuration.locking()
                .lockAcquisitionTimeout(60000l)
                .transaction().transactionManagerLookup(new DummyTransactionManagerLookup());
                // uncomment this line and exception is not thrown for some reason
                //.lockingMode(LockingMode.PESSIMISTIC);
        createClusteredCaches(2, configuration);
        waitForClusterToForm();
    }

    @Test(groups = "functional", expectedExceptions = { CacheException.class })
    public void testSyncReplTimeout() {
        AdvancedCache cache1 = cache(0).getAdvancedCache();
        AdvancedCache cache2 = cache(1).getAdvancedCache();
        cache2.addInterceptor(new CommandInterceptor() {
            @Override
            protected Object handleDefault(InvocationContext ctx, VisitableCommand cmd)
                    throws Throwable {
                // Add a delay
                Thread.sleep(100);
                return super.handleDefault(ctx, cmd);
            }
        }, 0);

        cache1.getCacheConfiguration().clustering().sync().replTimeout(10);
        cache2.getCacheConfiguration().clustering().sync().replTimeout(10);
        TestingUtil.blockUntilViewsReceived(10000, cache1, cache2);

        cache1.put("k", "v");
    }

}

Can someone help me understand why it is hiding exception with pessimistic locking enabled and how to fix that?

Update: I am using Infinispan 5.3.0.Final.

Was it helpful?

Solution

It's because Infinispan registers itself with the transaction manager by default as a "synchronization" instead of a full XA resource. Synchronizations are not allowed to throw XAExceptions in their afterCompletion() methods, and the transaction managers (including DummyTransactionManagerLookup) swallow any runtime exceptions.

In optimistic mode, the keys and values are replicated during beforeCompletion(), which is allowed to throw an exception in order to cancel the transaction.

In pessimistic mode, you should configure Infinispan to register as an XA resource instead:

   configuration.transaction().useSynchronization(false);

Edit: By default, DummyTransactionManager doesn't support XA transactions, so you also need to configure it for XA (or even better, use Narayana):

    DummyTransactionManager.getInstance().setUseXaXid(true);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top