openjpa-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Albert Lee (JIRA)" <>
Subject [jira] Commented: (OPENJPA-359) OptimisticLockException NOT thrown for entity using Timestamp Version when update from concurrent persistence contexts
Date Sat, 08 Sep 2007 19:49:29 GMT


Albert Lee commented on OPENJPA-359:

>> We need to also consider clustered environments -- this patch doesn't do much for
such environments. Of course, in a clustered environment, timestamp-based checks rely on clock
synchronization, which is a hard problem. 

When you say clustered environment, do you mean multiple appl servers (in a cluster) accessing
the same db server? This patch refines the time stamp granularity and improves version uniqueness.
It does not degrade the current implementation and will exhibit the exact behavior as far
as "clustering" is concern.  I agree with you that Versioning support in cluster environment
is a hard problem and it is not only for Timestamp but any type. Until there is a central
"server" that hands out unique version id, it will remain to be a insoluble problem.

>> The proposed change adds a synchronized block, which seems like a potential bottleneck;

The synchronized block is required to make sure the counter is updated correctly in multi-thread
scenario. This follows a similar pattern as implemented in the UUIDGenerator.  I have considered
the bottleneck condition and scaled down the instructions absolutely needed in the synchronized
block to improve concurrency.

>> I think I'd rather see us just put a Thread.currentThread().wait(<15 | 2>)
call into the versioning code.
Do you mean "Thread.currentThread().sleep(<15|2>)" ?  
First, one has to determine the value to sleep. This value varies a lot and depends on the
hardware platform and realistically should be determine at run-time.  Second, sleeping for
2ms per se is an artificial performance and concurrency inhibitors which I don't recommend.

We may be able to figure out other means to avoid the synchronized block but still get the
same result.

>> Note, of course, that this still won't solve the problem in a clustered environment.
Distributed system synchronization is always a hard problem to solve.  The initial time stamp
value is based on System.currentTimeMillis(), this means the first problem is to make sure
this base value is synchronized between all servers in the cluster. The second problem is
the increment value needs to be either synchronized and/or common between all servers.   

If we take a step back and say using Timestamp as version id is inherently problematic (the
same argument as using float as primary key) in cluster environment, all we can do is to provide
an implementation that can improve the possibility NOT to run into a problem condition, as
we already have encountered in our test scenario.

Albert Lee.

> OptimisticLockException NOT thrown for entity using Timestamp Version when update from
concurrent persistence contexts
> ----------------------------------------------------------------------------------------------------------------------
>                 Key: OPENJPA-359
>                 URL:
>             Project: OpenJPA
>          Issue Type: Bug
>          Components: jdbc
>    Affects Versions: 1.0.0
>         Environment: WIntel 32 
>            Reporter: Albert Lee
>            Priority: Minor
>         Attachments: OPENJPA-359.patch
> We ran a test using Timestamp as the version field in an entity, the following (pseudo)
test failed when an OptimisticLockException is expected:
>     em1.persist( e0(pk1) );
>     e1 = em1.find(pk1);
>     e2 = em2.find(pk1);
>     e1.setAttr( "new1");
>     e2.setAttr( "new2");
>     em1.merge( e1 );
>     em2.merge( e2 );    <<<< Expect an OptimisticLockException
> The cause of this problem is because the TimestampVersionStrategy.nextVersion returns
a java.sql.Timestamp(System.currentTimeMillis()); In the Wintel environment, the currentTimeMillis()
only has approximately 15ms resolution. When 2 subsequent Timestamp version objects are requested
within this 15ms interval, both has the same version value. Therefore the em2.merge does not
detected the versions difference between o1 and o2, hence no exception is thrown.
> Due to this behavior, the same test case may failed intermittenly depends on the currentTimeMillis()
resolution and the time when a timestamp version is created.  From some preliminary tests,
the resolution for  wintel, linux and z/os are about 15ms, 2ms and 2ms respectively.

This message is automatically generated by JIRA.
You can reply to this email to add a comment to the issue online.

View raw message