我有以下设置。
要通过Hibernate在DB中保存记录,我有以下工作流程
将JSON {id:1,name:"test",children:[...]}
发送到Spring MVC App并使用Jackson将其转换为对象图(如果它是现有实例,则JSON具有DB集中记录的正确ID
通过服务层调用将对象保存在DB中(详情如下)
服务层界面SomeObjectService
的保存功能在readOnly=false
和传播REQUIRED
此服务层SomeObjectServieImpl
的实现调用DAO保存
方法
DAO通过调用hibernate的合并来保存新数据,例如: hibernateTempate().merge(someObj)
hibernate merge
首先通过SELECT
我有一个连接到spring的EntityListener(我使用了这种技术Spring + EntityManagerFactory +Hibernate Listeners + Injection)并听取了@PostLoad
侦听器使用LockingServie
更新someObject
的一个字段以将其设置为已锁定(此实际上只应在通过Hibernate HQL加载someObject
时发生,SQL或Criteria调用,但也会在合并时调用)
LockingServie
有一个lock(someObj,userId)
函数,该函数也注明了@Transactional readOnly=false
和REQUIRED
通过调用Query query = sess.createQuery("update someObj set lockedBy=:userId");
然后进行更新
query.executeUpdate();
在合并加载了数据后,它开始更新someObject
并插入相关的子项(< = exacely here 死锁发生)
将JSON结果(这也包括新创建的对象ID)返回给客户端。
首先,问题出现在我身上
我可以通过MySQL看到
SHOW OPEN TABLES
子表(是对象图的一部分)被锁定。
有趣的事实是,someObj 表上不会出现死锁,而是代表孩子的表。
我有点迷失在这里。任何帮助都非常受欢迎。
顺便说一句,BTW可能会isolation级别让我摆脱这个问题吗?
答案 0 :(得分:1)
我最终使用了@ Bozho的HibernateExtendedJpaDialect
在此解释>> Hibernate, spring, JPS & isolation - custom isolation not supported
将隔离设置为 READ_UNCOMMITED
@Transactional(readOnly = false, propagation = Propagation.REQUIRED, isolation=Isolation.READ_UNCOMMITTED)
public Seizure merge(Seizure seizureObj);
我知道这不是一个非常好的解决方案,但至少这解决了我的问题。
如果有人想要详细说明,请询问......
答案 1 :(得分:0)
我不知道问题的解决方案,但我没有事务锁定方法。如果您需要手动锁定某些内容,请在另一种事务服务方法中进行。