On Sep 9, 2011, at 8:40 AM, Hans C. Poo wrote:
> I appreciate your answer, is really hard form me to imagine that
> synchronized, the natural java concurrency mechanism have not been requested
> before, optimistic or pessimistic locking fixes another situation, that
> sometimes may collide with test & set, but it's different.
Well, Cayenne is a part of a distributed system that at the minimum includes a
database and an app server. Moreover Cayenne is being used in massive appserver
clusters. So single VM Java "synchronized" can only go that far addressing a
special case.
> With respect to your answer:
> Create your own arbitrary lock object of course that is shared between all
> threads. If this has to be per-object lock, you may try using objects from a
> single shared ObjectContext, or build a concurrent Map of ObjectIds to use as
> locks.
>
> Is the use of a Custom Superclass a way to transparently implement this,
> implementing a method say sharedLock() ?
>
> And in the code call something like:
>
> synchronized(myObject.sharedLock()) {
>
>
>
> }
>
> May be in the core already exists a candidate shared representation of an
> single instance, that may serve for synchronize in...
So do you need one global lock or per-object lock? I assume the later.
Here is a class that does all you need here. You can either make it a static
addition to your DataObjects superclass, or (my own preferred way), keep it
somewhere else in the application scope. In Cayenne 3.1 I'd put it in DI
container.
class PerObjectLockManager {
private ConcurrentMap<ObjectId, ObjectId > ids = ...
Object objectLock(Persistent object) {
ObjectId newId = object.getObjectId();
ObjectId existingId = ids.putIfAbsent(newId, newId);
return existing != null ? existingId : newId;
}
}
Andrus