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






Reply via email to