1. 现场环境的异常如下:
org.springframework.dao.DeadlockLoserDataAccessException: SqlMapClient operation; SQL [];
--- The error occurred in com/broada/srvmonitor/dao/ibatis/maps/oracle/MonitorResource.xml.
--- The error occurred while applying a parameter map.
--- Check the MonitorResource.removeMonitorResource-InlineParameterMap.
--- Check the statement (update failed).
--- Cause: java.sql.SQLException: ORA-00060: 等待资源时检测到死锁
; nested exception is com.ibatis.common.jdbc.exception.NestedSQLException:
--- The error occurred in com/broada/srvmonitor/dao/ibatis/maps/oracle/MonitorResource.xml.
--- The error occurred while applying a parameter map.
--- Check the MonitorResource.removeMonitorResource-InlineParameterMap.
--- Check the statement (update failed).
--- Cause: java.sql.SQLException: ORA-00060: 等待资源时检测到死锁
2.找到com/broada/srvmonitor/dao/ibatis/maps/oracle/MonitorResource.xml
得出结论是表锁定 ,跟SM_RESOURCE表有关
3.通过pl/sql获取SM_RESOURCE的表设计
从上面的SM_RESOURCE的表设计可以看到该表有一个主键和两个外键,因为可以推断出此表死锁的两种情况
A情况 SM_RESOURCE表死锁了
SM_RESOURCE有两个外键,如图
可以得出该表是另外两个表的从表,当另外两个表中的其中一个表进行DML操作时,就会锁定SM_RESOURCE表,所以当bcc删除检测器,需要对SM_RESOURCE表进行操作的时候,此时就要等待其他主表对它释放,如果那个主表不释放SM_RESOURCE,就会导致死锁。
B情况. SM_RESOURCE 的从表被锁定
根据上图,可以得出,主表SM_RESOURCE有五个从表
当bcc删除检测器,对SM_RESOURCE表进行操作的时候,
SM_RESOURCE表先会锁定五个从表,如果这五个从表的其中一个表被其他表占用 ,那么就会等待其他表释放资源,如果其他表占着不放,就导致死锁。
4. 解决方案:在外键上添加索引
6月22日,解决了A情况,SM_RESOURCE表的两个外键添加了索引,结果现场出现了假死现象(阻塞情况),接着6月25日把SM_RESOURCE表的从表的外键都加了索引,终于解决了问题,删除检测器没有报错。
主表操作时,会锁定从表进行检查
没索引的话会对从表全表锁定
有索引的话会行锁定