【发布时间】:2011-12-18 08:31:16
【问题描述】:
我有以下设置。
- 春季 3.0.5
- 休眠 3.5.6
- MySql 5.1
要通过 Hibernate 在数据库中保存记录,我有以下工作流程
-
将 JSON
{id:1,name:"test",children:[...]}发送到 Spring MVC 应用程序并使用 Jackson 将其转换为对象图(如果它是现有实例,则 JSON 具有数据库集中记录的正确 ID -
通过服务层调用将对象保存在数据库中(详情如下)
服务层接口
SomeObjectService的save函数上面有@Transactional注解,有readOnly=false和PropagationREQUIRED这个服务层的实现
SomeObjectServieImpl调用DAO保存 方法DAO 通过调用 hibernate 的合并来保存新数据,例如
hibernateTempate().merge(someObj)hibernate
merge首先通过SELECT从数据库加载对象我有一个连接到 spring 的 EntityListener(我使用了这种技术 Spring + EntityManagerFactory +Hibernate Listeners + Injection)并监听
@PostLoad
1234563 /strong> 但在合并时也会被调用)
LockingServie有一个函数lock(someObj,userId),它也用@Transactional 注释,带有readOnly=false和REQUIRED通过调用
Query query = sess.createQuery("update someObj set lockedBy=:userId");进行更新,然后query.executeUpdate();merge 加载数据后,它开始更新
someObject并插入相关子项(发生死锁的地方)将 JSON 结果(这也包括新创建的对象 ID)返回给客户端。
问题在我看来是第一个
- 记录被加载到事务中
- 然后在另一个(内部)事务中更改
- 然后应该使用外部事务的数据再次更新,但由于它被锁定而无法更新。
我可以通过 MySQL 看到
SHOW OPEN TABLES
子表(对象图的一部分)被锁定。
有趣的事实是,死锁不会发生在 someObj 表上,而是发生在代表孩子的表上。
我有点迷路了。任何帮助都非常受欢迎。
顺便说一句,isolation 级别可以让我摆脱这个问题吗?
【问题讨论】:
标签: mysql spring deadlock spring-transactions