I have the following setup.
- Spring 3.0.5
- Hibernate 3.5.6
- MySql 5.1
To save a record in the DB via Hibernate I have the following workflow
send JSON
{id:1,name:"test",children:[...]}
to Spring MVC App and use Jackson to transform it into an object graph (if it is an existing instance the JSON has the proper ID of the record in the DB setsave the object in DB via service layer call (details below)
the save function of service layer interface
SomeObjectService
has the @Transactional annotation on it withreadOnly=false
and PropagationREQUIRED
the implementation of this service layer
SomeObjectServieImpl
calls the DAO save methodthe DAO saves the new data via a call of hibernate's merge e.g.
hibernateTempate().merge(someObj)
hibernate
merge
loads the object first from the DB viaSELECT
I have a EntityListener who is wired to spring (I used this technique Spring + EntityManagerFactory +Hibernate Listeners + Injection) and listens to
@PostLoad
The listener uses a
LockingServie
to updates one field ofsomeObject
to set it as locked (this should actually only happen whensomeObject
is loaded via Hibernate HQL,SQL or Criteria calls but gets called also on merge)the
LockingServie
has a functionlock(someObj,userId)
which is also annotated with @Transactional withreadOnly=false
andREQUIRED
the update happens via a call of
Query query = sess.createQuery("update someObj set lockedBy=:userId");
and thenquery.executeUpdate();
after merge has loaded the data it start with updating
someObject
and inserting relevant children (<= exacely here is the point where the deadlock happens)
return JSON result (this also includes the newly created object ID) back to client.
The problem seems for me that first
- the record gets loaded in a transaction
- then gets changed in another (inner-)transaction
- and then should get updated again with the data of the outer transaction but can't get updated because it is locked.
I can see via MySQL's
SHOW OPEN TABLES
that a child table (that is part of the object graph) is locked.
Interesting fact is that the deadlock doesn't occur on the someObj table but rather on a table that represents a child.
I am a bit lost here. Any help is more than welcome.
BTW can maybe the isolation level get me out of this problem here?