[
https://issues.jboss.org/browse/JBTM-2396?page=com.atlassian.jira.plugin....
]
Mark Little commented on JBTM-2396:
-----------------------------------
There were a few things at work here.
(i) the test used a couple of containers and cloned the object. That's legal but it
exposed a bug in the way in which locks were saved and restored. They were created (in the
first container) as OptimisticLock but restored (in the second container) as Lock which
caused conflicts. That's fixed now but I may revisit the fix. See
https://issues.jboss.org/browse/JBTM-2399 for more details.
(ii) the OptimisticLock wasn't created by InvocationHandler, as you mentioned.
(iii) because the test uses two containers and object invocations happen before any
initial state has been saved for the instance, the activate for the copy fails -
there's no state to load. This is a known issue
(
https://issues.jboss.org/browse/JBTM-1732). I changed the test to work around it for
now.
Investigate whether OCC implementation is unexpectedly checking locks
during @WriteLock methods rather than delaying to commit time
-----------------------------------------------------------------------------------------------------------------------------------
Key: JBTM-2396
URL:
https://issues.jboss.org/browse/JBTM-2396
Project: JBoss Transaction Manager
Issue Type: Task
Components: STM
Reporter: Tom Jenkinson
Assignee: Mark Little
Attachments: OptimisticLockUnitTest.java
While checking out the STM work I tried to observe the difference between the OCC and PCC
variants of the framework. During my testing I was not able to distinguish a difference
between the two implementations.
Consider the following test:
{code}
// gonna confess here, I am using two containers as I thought it might separate better
but I don't actually think this is required to use the two containers to get the
separation as the two transactions should I create should be doing that?
Container<Atomic> theContainer1 = new Container<Atomic>();
Container<Atomic> theContainer2 = new Container<Atomic>();
// Setting up the two references to the STM object
final Atomic obj1 = theContainer1.create(new ExampleSTM());
final Atomic obj2 = theContainer2.clone(new ExampleSTM(), obj1);
// Creating a transaction and calling the @WriteLock method set() on it but
don't commit the tx
AtomicAction a = new AtomicAction();
a.begin();
obj1.set(1234); // Don't commit this yet - I want to check that a conflicting
set() doesn't get the lockexception until commit()
// Setting up a second independent transaction and calling the @WriteLock method
set() on it again
AtomicAction.suspend();
AtomicAction b = new AtomicAction();
b.begin();
// Now, in my understanding calling this method should only throw a LockException
for pessimistic locking, but with the current implementation the Lock throws a conflict
now
obj2.set(12345); // This throws an exception even for @Optimisitic
// the rest of the test commits the two txs, but IMO as I am using @Optimistic I
should not have got the LockException on the second set() so the test failed
{code}
Whether the Atomic interface is annotated with either @Optimisitic (or ommitted/default
@Pessimisitc) the second @WriteLock set(int) call results in a lockexception being thrown.
This is contrary to my expectations for OCC where I would expect to observe the set()
being allowed but validation to be performed during commit and the commit to fail.
From my reading of
STM/src/main/java/org/jboss/stm/internal/reflect/InvocationHandler.java I can see that
this class (nor any of the other main classes) uses the OptimisticLock (which appears to
suppress lock conflicts). I can see it uses OptimisticLockRecord which may do the
validation correctly but my test fails because the second set(int) is allowed.
--
This message was sent by Atlassian JIRA
(v6.3.15#6346)