Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inconsistent behavior when removing from TransactionalMap while key is locked on IMap #7587

Closed
ttaomae opened this issue Feb 23, 2016 · 1 comment

Comments

Projects
None yet
3 participants
@ttaomae
Copy link

commented Feb 23, 2016

In order to avoid trying to remove an entry that may have already been removed in another, uncommitted transaction (so that we don't block unnecessarily), we first check IMap.tryLock before performing TransactionalMap.remove. For example:

if (map.tryLock("foo")) {
    txnMap.remove("foo");
}

This works as we expect when using local transaction on either a member or client and when using XA transactions (with Atomikos as the transaction manager; we have not tested with other transaction managers) if the operations occur on a member. However, if this occurs on a client in an XA transaction, we receive the following exception: com.hazelcast.transaction.TransactionException: Transaction couldn't obtain lock for the key: foo.

The code below reproduces this issue. Changing the client and xa flags allows you to test the different circumstances.

public static void tryLockTest() throws Exception
{
    final boolean client = true;
    final boolean xa = true;

    // Atomikos TransactionManager
    TransactionManager tm = new UserTransactionManager();

    // get HazelcastInstance
    HazelcastInstance hzInstance;
    if (client) {
        Hazelcast.newHazelcastInstance();
        hzInstance = HazelcastClient.newHazelcastClient();
    }
    else {
         hzInstance = Hazelcast.newHazelcastInstance();
    }

    // get map
    IMap<String, String> map = hzInstance.getMap("map");
    map.put("foo", "bar");

    // start transaction
    TransactionContext txnCtx;
    if (xa) {
        tm.begin();
        HazelcastXAResource hzXaResource = hzInstance.getXAResource();
        tm.getTransaction().enlistResource(hzXaResource);
        txnCtx = hzXaResource.getTransactionContext();
    }
    else {
        txnCtx = hzInstance.newTransactionContext();
        txnCtx.beginTransaction();
    }

    // remove "foo" from transactional map
    if (map.tryLock("foo")) {
        txnCtx.getMap("map").remove("foo");
        System.out.println("removed \"foo\"");
    }

    // commit transaction
    if (xa) {
        tm.commit();
    }
    else {
        txnCtx.commitTransaction();
    }
}

This was tested with versions 3.5.5 and 3.6

@jerrinot jerrinot modified the milestones: 3.6.2, 3.7 Feb 24, 2016

@gurbuzali gurbuzali self-assigned this Feb 24, 2016

@gurbuzali

This comment has been minimized.

Copy link
Member

commented Feb 24, 2016

Thank you for pointing it out. I've found the problem, a fixing PR is in order.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.