[ 
https://issues.apache.org/jira/browse/OPENJPA-359?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12525944
 ] 

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: https://issues.apache.org/jira/browse/OPENJPA-359
>             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.

Reply via email to