3

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

  1. 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 set

  2. save the object in DB via service layer call (details below)

    • the save function of service layer interface SomeObjectService has the @Transactional annotation on it with readOnly=false and Propagation REQUIRED

    • the implementation of this service layer SomeObjectServieImpl calls the DAO save method

    • the 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 via SELECT

    • 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 of someObject to set it as locked (this should actually only happen when someObject is loaded via Hibernate HQL,SQL or Criteria calls but gets called also on merge)

    • the LockingServie has a function lock(someObj,userId) which is also annotated with @Transactional with readOnly=false and REQUIRED

    • the update happens via a call of Query query = sess.createQuery("update someObj set lockedBy=:userId"); and then query.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)

  3. return JSON result (this also includes the newly created object ID) back to client.

The problem seems for me that first

  1. the record gets loaded in a transaction
  2. then gets changed in another (inner-)transaction
  3. 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?

4

2 回答 2

1

我最终使用了@Bozho'sHibernateExtendedJpaDialect

此处解释 >> Hibernate、spring、JPS 和隔离 - 不支持自定义隔离

将隔离设置为READ_UNCOMMITED

@Transactional(readOnly = false, propagation = Propagation.REQUIRED, isolation=Isolation.READ_UNCOMMITTED)
public Seizure merge(Seizure seizureObj);

我知道这不是一个很好的解决方案,但至少这解决了我的问题。

如果有人想有详细的描述,请询问...

于 2012-01-25T17:35:47.107 回答
0

我不知道问题的解决方案,但我不会有事务锁定方法。如果您需要手动锁定某些内容,请在另一个事务服务方法中进行。

于 2011-11-19T21:08:37.867 回答