Andrus,
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.
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...
Thanks
Hans
----- Mensaje original -----
De: "Andrus Adamchik" <[email protected]>
Para: [email protected]
Enviados: Jueves, 1 de Septiembre 2011 15:40:39
Asunto: Re: Test & Set business logic using synchronized blocks
Synchronizing on a DataObject is not going to help across contexts as each
context has its owen copy of an object. But you can 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.
Also since context sync events are propagated asynchronously, you will have to
use the database as an authoritative source of data. E.g.:
synchronized(myLock) {
context.invalidateObject(Collections.singleton(myObject));
if (myObject.getEsInactivo()) {
}
}
Andrus
On Aug 29, 2011, at 9:10 AM, Hans C. Poo wrote:
> Hi,
>
> ¿ Is it possible to use Test & Set business logic using synchronized blocks
> in persistent instances ?
>
> Each objectContext has its own instances, then there may be many copies of
> the same object identity (id) in memory, that keep in sync with each other if
> you commit, ¿ Is it possible to use normal java synchronized block ?
>
> I've build the next test using two threads, and when it runs, the field is
> modified twice, under normal java concepts, only one thread should succeed.
>
> Note: Factory, is a repository with static methods to manage persistence
> (finally calls ObjectContext and DataContext).
>
>
> package cl.company.test;
>
> import cl.company.domain.Usuario;
> import cl.company.domain.Factory;
>
> /**
> * Concurrency over same instance, test & set. * @author hans
> *
> */
> public class TestConcurrenciaCayenne implements Runnable {
>
> private static final int USER_ID = 1000;
> String name;
>
> public TestConcurrenciaCayenne(String name) {
> this.name = name;
> }
>
> public static void main(String[] args) {
>
> Factory.createAndBindDataContext();
>
> Usuario c = Factory.getUsuario(USER_ID);
> c.setEsInactivo(true);
> Factory.commit();
>
> TestConcurrenciaCayenne t1 = new TestConcurrenciaCayenne("t1");
> TestConcurrenciaCayenne t2 = new TestConcurrenciaCayenne("t2");
> new Thread(t1).start();
> new Thread(t2).start();
> }
>
> @Override
> public void run() {
>
> Factory.createAndBindDataContext();
>
> Usuario c = Factory.getUsuario(USER_ID);
> System.out.println("Before synchronized block " + this.name);
> synchronized (c) {
>
> System.out.println("Inside the block " + this.name);
> if (c.getEsInactivo()) {
> try {
> Thread.sleep(2000);
> } catch (InterruptedException e) {
> e.printStackTrace();
> }
> c.setEsInactivo(false);
> System.out.println("Modifyin " + this.name);
> }
>
> Factory.commit();
>
> }
>
> }
>
> }
>
>
>
> Thanks
> Hans
>