Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write Java code that is synchronized on an instance of an entity

I'm using Hibernate and Spring and I want to write Service code to cater for the scenario where, in two separate threads, a DAO is used to fetch an entity instance by id, and it is the same id / database row in each case, and I don't want a given method to run concurrently in both threads for that entity instance.

I'm not sure whether it is possible to write...

synchronized(entity) {}

or whether this is not possible because each thread could have created a different instance of the object in memory when retrieving from the DAO, both referring to the same entity instance.

If indeed it is possible for Hibernate to create multiple objects in memory for the same entity instance, what is the best way to do what I am trying to do?

like image 262
Martin Bamford Avatar asked Jan 21 '14 16:01

Martin Bamford


People also ask

How do you declare a synchronized variable in Java?

Use the synchronized keyword. Using the synchronized keyword on the methods will require threads to obtain a lock on the instance of sample . Thus, if any one thread is in newmsg() , no other thread will be able to get a lock on the instance of sample , even if it were trying to invoke getmsg() .

What is synchronized statement in Java?

Synchronized keyword in JavaThe process of allowing only a single thread to access the shared data or resource at a particular point of time is known as Synchronization. This helps us to protect the data from the access by multiple threads. Java provides the mechanism of synchronization using the synchronized blocks.


1 Answers

That won't work. Hibernate might (and often will) return a different instance when you load data from the database.

The reason for this is that two threads might want to access the same object at the same time. If Hibernate would give both the same instance, then changes by one thread might (or not) be visible to the second thread.

To achieve what you want, you need a central registry where you can get a lock for an entity by ID. That way, every thread can do:

 Object lock = lockFactory.getLock(id);
 synchronized(lock) {...}

Your factory can then make sure that all threads get the same lock for the same ID.

like image 182
Aaron Digulla Avatar answered Oct 16 '22 02:10

Aaron Digulla