cayenne-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Hans C. Poo" <h...@welinux.cl>
Subject Re: Test & Set business logic using synchronized blocks
Date Fri, 09 Sep 2011 12:40:18 GMT
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" <andrus@objectstyle.org>
Para: user@cayenne.apache.org
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
> 


Mime
View raw message