java.sql.SQLException: ORA-00060: 等待资源时检测到死锁

 

一:首先看异常信息:

============异常信息开始=================================================================================================================
Hibernate: delete from GZK_NR where MLID=?
Hibernate: delete from GZK_LB where LBID=?
Hibernate: delete from GZK_LB where LBID=?
Hibernate: delete from GZK_LB where LBID=?
java.lang.reflect.InvocationTargetException
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
 at java.lang.reflect.Method.invoke(Method.java:597)
 at com.cee.common.AbstractMultiActionFormController.processFormSubmission(AbstractMultiActionFormController.java:121)
 at com.cee.common.NbwController.handleRequestInternal(NbwController.java:84)
 at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:153)
 at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48)
 at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:875)
 at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:807)
 at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:571)
 at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:511)
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
 at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:96)
 at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
 at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
 at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
 at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
 at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
 at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
 at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
 at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
 at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
 at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
 at java.lang.Thread.run(Thread.java:619)
Caused by: org.hibernate.exception.LockAcquisitionException: could not execute update query
 at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:87)
 at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
 at org.hibernate.hql.ast.exec.BasicExecutor.execute(BasicExecutor.java:87)
 at org.hibernate.hql.ast.QueryTranslatorImpl.executeUpdate(QueryTranslatorImpl.java:398)
 at org.hibernate.engine.query.HQLQueryPlan.performExecuteUpdate(HQLQueryPlan.java:259)
 at org.hibernate.impl.SessionImpl.executeUpdate(SessionImpl.java:1142)
 at org.hibernate.impl.QueryImpl.executeUpdate(QueryImpl.java:94)
 at com.cee.common.GenericDAO.executeHQL(GenericDAO.java:77)
 at com.cee.pwgh.sysExt.dao.GzkLbDAO.deleteGzkLbByLbid(GzkLbDAO.java:59)
 at com.cee.pwgh.sysExt.service.GzkLbManager.process(GzkLbManager.java:72)
 at com.cee.pwgh.sysExt.service.GzkLbManager$$FastClassByCGLIB$$555d2384.invoke(<generated>)
 at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:149)
 at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:700)
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
 at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
 at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:635)
 at com.cee.pwgh.sysExt.service.GzkLbManager$$EnhancerByCGLIB$$7cb32887.process(<generated>)
 at com.cee.pwgh.sysExt.web.action.GzkLbController.process(GzkLbController.java:43)
 ... 30 more
Caused by: java.sql.SQLException: ORA-00060: 等待资源时检测到死锁

 at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
 at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:331)
 at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:288)
 at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:745)
 at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:219)
 at oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:970)
 at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1190)
 at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3370)
 at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:3454)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
 at java.lang.reflect.Method.invoke(Method.java:597)
 at org.logicalcobwebs.proxool.ProxyStatement.invoke(ProxyStatement.java:100)
 at org.logicalcobwebs.proxool.ProxyStatement.intercept(ProxyStatement.java:57)
 at oracle.jdbc.OracleStatement$$EnhancerByProxool$$f4e9fcb7.executeUpdate(<generated>)
 at org.hibernate.hql.ast.exec.BasicExecutor.execute(BasicExecutor.java:78)
 ... 46 more
2011-8-22 18:11:22 org.apache.catalina.core.StandardWrapperValve invoke
严重: Servlet.service() for servlet pwgh threw exception
java.sql.SQLException: ORA-00060: 等待资源时检测到死锁

 at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
 at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:331)
 at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:288)
 at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:745)
 at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:219)
 at oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:970)
 at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1190)
 at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3370)
 at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:3454)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(

==============异常信息结束===============================================================================================================
二:再看涉及到的两个表结构,
原始建表的sql语句如下:
create table GZK_LB  (
   LBID                 VARCHAR2(32)                    not null,
   MC                   VARCHAR2(60),
   PQ                   VARCHAR2(32),
   YEAR                 VARCHAR2(4)                     not null,
   constraint PK_GZK_LB primary key (LBID)
);

create table GZK_NR  (
   NRID                 VARCHAR2(32)                    not null,
   MLID                 VARCHAR2(32),
   GZID                 VARCHAR2(32),
   DYSQL                VARCHAR2(100),
   DYB                  VARCHAR2(40),
   MS                   VARCHAR2(100),
   MC                   VARCHAR2(60),
   constraint PK_GZK_NR primary key (NRID)
);

alter table GZK_NR add constraint FK_GZK_NR_REFERENCE_GZK_LB foreign key (MLID) references GZK_LB (LBID);

表GZK_NR.MLID上有一个外键引用GZK_LB.LBID。

下面是通过toad拷贝出来的数据库中实际的表结构。
==============表结构开始===============================================================================================================
CREATE TABLE GZK_LB
(
  LBID  VARCHAR2(32 BYTE)                       NOT NULL,
  MC    VARCHAR2(60 BYTE),
  PQ    VARCHAR2(32 BYTE),
  YEAR  VARCHAR2(4 BYTE)                        NOT NULL
)
TABLESPACE PWGH
PCTUSED    0
PCTFREE    10
INITRANS   10
MAXTRANS   255
STORAGE    (
            INITIAL          64K
            MINEXTENTS       1
            MAXEXTENTS       2147483645
            PCTINCREASE      0
            BUFFER_POOL      DEFAULT
           )
LOGGING
NOCOMPRESS
NOCACHE
NOPARALLEL
MONITORING;

CREATE UNIQUE INDEX PK_GZK_LB ON GZK_LB
(LBID)
LOGGING
TABLESPACE PWGH
PCTFREE    10
INITRANS   10
MAXTRANS   255
STORAGE    (
            INITIAL          64K
            MINEXTENTS       1
            MAXEXTENTS       2147483645
            PCTINCREASE      0
            BUFFER_POOL      DEFAULT
           )
NOPARALLEL;


ALTER TABLE GZK_LB ADD (
  CONSTRAINT PK_GZK_LB
 PRIMARY KEY
 (LBID)
    USING INDEX
    TABLESPACE PWGH
    PCTFREE    10
    INITRANS   10
    MAXTRANS   255
    STORAGE    (
                INITIAL          64K
                MINEXTENTS       1
                MAXEXTENTS       2147483645
                PCTINCREASE      0
               ));


CREATE TABLE GZK_NR
(
  NRID   VARCHAR2(32 BYTE)                      NOT NULL,
  MLID   VARCHAR2(32 BYTE),
  GZID   VARCHAR2(32 BYTE),
  DYSQL  VARCHAR2(100 BYTE),
  DYB    VARCHAR2(40 BYTE),
  MS     VARCHAR2(100 BYTE),
  MC     VARCHAR2(60 BYTE)
)
TABLESPACE PWGH
PCTUSED    0
PCTFREE    10
INITRANS   1
MAXTRANS   255
STORAGE    (
            INITIAL          64K
            MINEXTENTS       1
            MAXEXTENTS       2147483645
            PCTINCREASE      0
            BUFFER_POOL      DEFAULT
           )
LOGGING
NOCOMPRESS
NOCACHE
NOPARALLEL
MONITORING;


CREATE INDEX INDEX_GZK_NR_MLID ON GZK_NR
(MLID)
LOGGING
TABLESPACE PWGH
PCTFREE    10
INITRANS   2
MAXTRANS   255
STORAGE    (
            INITIAL          64K
            MINEXTENTS       1
            MAXEXTENTS       2147483645
            PCTINCREASE      0
            BUFFER_POOL      DEFAULT
           )
NOPARALLEL;


CREATE UNIQUE INDEX PK_GZK_NR ON GZK_NR
(NRID)
LOGGING
TABLESPACE PWGH
PCTFREE    10
INITRANS   2
MAXTRANS   255
STORAGE    (
            INITIAL          64K
            MINEXTENTS       1
            MAXEXTENTS       2147483645
            PCTINCREASE      0
            BUFFER_POOL      DEFAULT
           )
NOPARALLEL;


ALTER TABLE GZK_NR ADD (
  CONSTRAINT PK_GZK_NR
 PRIMARY KEY
 (NRID)
    USING INDEX
    TABLESPACE PWGH
    PCTFREE    10
    INITRANS   2
    MAXTRANS   255
    STORAGE    (
                INITIAL          64K
                MINEXTENTS       1
                MAXEXTENTS       2147483645
                PCTINCREASE      0
               ));


ALTER TABLE GZK_NR ADD (
  CONSTRAINT FK_GZK_NR_REFERENCE_GZK_LB
 FOREIGN KEY (MLID)
 REFERENCES GZK_LB (LBID));

ALTER TABLE GZK_NR ADD (
  CONSTRAINT FK_GZK_NR_REFERENCE_GZK_MB
 FOREIGN KEY (GZID)
 REFERENCES GZK_MB (GZID));

 


==============表结构结束===============================================================================================================

三:触发异常的原因是因为批量的执行如下的语句:
delete from GZK_NR where MLID=?
delete from GZK_LB where LBID=?

即:先删除字子表GZK_NR的一些记录,然后删除这些记录通过外键对应的表GZK_LB中那条记录。

感觉这么做是没有问题的,但是却引发上述的异常:java.sql.SQLException: ORA-00060: 等待资源时检测到死锁。
似乎是表GZK_LB被锁住,不能及时释放。

四:解决办法:
办法1:禁用外键,
alter table GZK_NR disable constraint FK_GZK_NR_REFERENCE_GZK_LB;

办法2:保留外键,在表GZK_NR的外键列MLID上建立索引,并且需要是asc索引
create index index_GZK_NR_mlid on GZK_NR(Mlid asc);
如果建立desc索引,
create index index_GZK_NR_mlid on GZK_NR(Mlid DESC);
上述异常仍然存在。

五:结论。
由此看出,如果要删除存在外键的两个表的数据,需要在子表的外键列上建立asc的索引,然后先删除子表数据,
再删除相应父表的记录。

itpub上有网友讨论这个问题的帖子:
http://www.itpub.net/viewthread.php?tid=1259329&extra=&page=1

 

你可能感兴趣的:(table,null,delete,buffer,byte,reference)