我有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对象时死锁。有经验的大侠们能判断出问题出在哪里吗?

解决方案 »

  1.   

    关联这么多表 你在做投票吧。。?换个顺序 先DELETE原来的BC 然后创建BC 然后跟更新A 如果是创建的话 顺序则是创建 A B C 
      

  2.   


    这三个表确实是这样的逻辑关系,构成一个3级的层次关系。
    我只需要update实体entityA,下面的两级实体会自动保存,因为是级联更新的。至于是先insert还是先delete都是由hibernate控制的,并不是我自己写的程序执行的SQL。
      

  3.   

    你可以决定你调用方法的顺序 这是更新每个实体 所以我觉得跟事务弄不上太大的关系(一般的事务是要有的)实际上你需要进行的操作如下A表的增删改
    B表的增删
    C表的增删您觉得这里的那个功能需要特殊的事务?
      

  4.   

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

  5.   


    我说了一般的事务是要有的 但你的问题跟事务没太大关系 你只需要注意更新顺序便可以了先更新A 然后再将A放到B和C 顺序就是这样
      

  6.   


    按照你的说法不要使用级联更新来做?因为我使用的是级联更新,也就不存在先更新A还是B或C,而是只需要更新A,B和C会自动保存到数据库,我们项目组的约定是这种父子关系的表都通过级联来做。
      

  7.   

    可以不用级联更新来做 但是保存B和C的时候一定要有A的持久状态的对象 才行 。。你等谁?。。
      

  8.   


    有日志文件:
    07-30 08:59:51,017 ERROR (org.hibernate.util.JDBCExceptionReporter:78) - ORA-00060: deadlock detected while waiting for resource07-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]