hibernate级联更新偶尔锁表的问题

zhun_yi 2009-08-04 04:50:02
我有3个实体类:entityA,entityB,entityC,分别对应数据库中的A,B,C3个表,表C是表B的子表,而表B是表A的子表

配置了级联关系:@Cascade({org.hibernate.annotations.CascadeType.ALL,org.hibernate.annotations.CascadeType.DELETE_ORPHAN})


现在我每次修改实体entityA的时候是启动事务,先删除它下面所有的entityB和entityC对象,然后再重新创建下属的entityB和entityC对象,然后调用update(entityA)级联更新。

这样操作每次输出的SQL是先insert新创建的entityB和entityC对象,然后update entityA对象,最后delete原来的entityB和entityC对象。

问题:一般情况下是正常的,偶尔会出现死锁的情况,查看数据库的trace文件发现是在delete entityB对象时死锁。

有经验的大侠们能判断出问题出在哪里吗?
...全文
692 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
xuexijava 2009-08-09
  • 打赏
  • 举报
回复
关注
BearKin 2009-08-07
  • 打赏
  • 举报
回复
不行你把具体代码和数据库表的结构拿出来看下吧。。
zhun_yi 2009-08-07
  • 打赏
  • 举报
回复
真的没有人能找到原因么,下周一结贴。
BearKin 2009-08-06
  • 打赏
  • 举报
回复

刚才去搜索 没找到错误原因 LZ多福。。
lytcd 2009-08-06
  • 打赏
  • 举报
回复
来学习的 期待大牛
zhun_yi 2009-08-06
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 bearkin 的回复:]
这个不清楚 或许你更新的顺序有问题 而且你凭什么断定就是锁表 异常的有?
[/Quote]

有日志文件:
07-30 08:59:51,017 ERROR (org.hibernate.util.JDBCExceptionReporter:78) - ORA-00060: deadlock detected while waiting for resource

07-30 08:59:51,020 ERROR (org.hibernate.event.def.AbstractFlushingEventListener:301) - Could not synchronize database state with session
org.hibernate.exception.LockAcquisitionException: could not delete: [com.zoomlion.pms.perApply.model.PerIndex#4028803a22c665250122c92b7ea6135e]
zhun_yi 2009-08-05
  • 打赏
  • 举报
回复
继续等。。。
zhun_yi 2009-08-05
  • 打赏
  • 举报
回复
在线等。。。
zhun_yi 2009-08-05
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 bearkin 的回复:]
引用 10 楼 zhun_yi 的回复:
整个过程应该属于一个事务,某一个失败的话整个过程就失败。

我说了我使用的是级联更新,好处就是只需要更新主表,子表会自动级联保存,而并不需要自己去处理子表的保存。设置好这3种实体的关系后,只需要一个保存到数据库的语句:***DAO.update(entityA);


我说了一般的事务是要有的 但你的问题跟事务没太大关系 你只需要注意更新顺序便可以了

先更新A 然后再将A放到B和C 顺序就是这样
[/Quote]

按照你的说法不要使用级联更新来做?因为我使用的是级联更新,也就不存在先更新A还是B或C,而是只需要更新A,B和C会自动保存到数据库,我们项目组的约定是这种父子关系的表都通过级联来做。
BearKin 2009-08-05
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 zhun_yi 的回复:]
整个过程应该属于一个事务,某一个失败的话整个过程就失败。

我说了我使用的是级联更新,好处就是只需要更新主表,子表会自动级联保存,而并不需要自己去处理子表的保存。设置好这3种实体的关系后,只需要一个保存到数据库的语句:***DAO.update(entityA);
[/Quote]

我说了一般的事务是要有的 但你的问题跟事务没太大关系 你只需要注意更新顺序便可以了

先更新A 然后再将A放到B和C 顺序就是这样
zhun_yi 2009-08-05
  • 打赏
  • 举报
回复
整个过程应该属于一个事务,某一个失败的话整个过程就失败。

我说了我使用的是级联更新,好处就是只需要更新主表,子表会自动级联保存,而并不需要自己去处理子表的保存。设置好这3种实体的关系后,只需要一个保存到数据库的语句:***DAO.update(entityA);
BearKin 2009-08-05
  • 打赏
  • 举报
回复
你可以决定你调用方法的顺序 这是更新每个实体 所以我觉得跟事务弄不上太大的关系(一般的事务是要有的)

实际上你需要进行的操作如下

A表的增删改
B表的增删
C表的增删

您觉得这里的那个功能需要特殊的事务?
zhun_yi 2009-08-05
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 bearkin 的回复:]
关联这么多表 你在做投票吧。。?换个顺序 先DELETE原来的BC 然后创建BC 然后跟更新A 如果是创建的话 顺序则是创建 A B C
[/Quote]

这三个表确实是这样的逻辑关系,构成一个3级的层次关系。
我只需要update实体entityA,下面的两级实体会自动保存,因为是级联更新的。至于是先insert还是先delete都是由hibernate控制的,并不是我自己写的程序执行的SQL。
zhun_yi 2009-08-05
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 liushaoyi0704 的回复:]
看看有没有事务嵌套。
[/Quote]


检查没有事务嵌套,整个过程处于一个事务里面,里面再没有另外的事务。
BearKin 2009-08-05
  • 打赏
  • 举报
回复
关联这么多表 你在做投票吧。。?换个顺序 先DELETE原来的BC 然后创建BC 然后跟更新A 如果是创建的话 顺序则是创建 A B C
化外之民 2009-08-05
  • 打赏
  • 举报
回复
看看有没有事务嵌套。
zhun_yi 2009-08-05
  • 打赏
  • 举报
回复
顶上去
BearKin 2009-08-05
  • 打赏
  • 举报
回复
这个不清楚 或许你更新的顺序有问题 而且你凭什么断定就是锁表 异常的有?
zhun_yi 2009-08-05
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 bearkin 的回复:]
可以不用级联更新来做 但是保存B和C的时候一定要有A的持久状态的对象 才行 。。你等谁?。。
[/Quote]

我是想知道我那么做为什么会导致锁表,只是偶尔。
sunnyfun888 2009-08-05
  • 打赏
  • 举报
回复
不delete,用saveOrUpdate
加载更多回复(4)

67,512

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧