尝试更新时发生Hibernate:LockAcquisitionException

时间:2019-02-19 10:14:39

标签: java mysql hibernate rest hql

我有2个表,ProductProductCategoryProduct表的外键为ProductCategory

我正在构建REST API,并且试图通过Product删除ProductCategory。我正在使用Hibernate,数据库是MySQL

请检查以下代码。

Product.java

public class Product  implements java.io.Serializable {


     private Integer idproduct;
     private ProductCategory productCategory;
     private String productName;
     private Date deleteTimestamp;
     private Date dateCreated;
     private Date lastUpdated;

    public Product() {
    }


    public Product(ProductCategory productCategory, String productName, Date lastUpdated) {
        this.productCategory = productCategory;
        this.productName = productName;
        this.lastUpdated = lastUpdated;
    }
    public Product(ProductCategory productCategory, String productName, Date deleteTimestamp, Date dateCreated, Date lastUpdated) {
       this.productCategory = productCategory;
       this.productName = productName;
       this.deleteTimestamp = deleteTimestamp;
       this.dateCreated = dateCreated;
       this.lastUpdated = lastUpdated;
    }

    public Integer getIdproduct() {
        return this.idproduct;
    }

    public void setIdproduct(Integer idproduct) {
        this.idproduct = idproduct;
    }
    public ProductCategory getProductCategory() {
        return this.productCategory;
    }

    public void setProductCategory(ProductCategory productCategory) {
        this.productCategory = productCategory;
    }
    public String getProductName() {
        return this.productName;
    }

    public void setProductName(String productName) {
        this.productName = productName;
    }
    public Date getDeleteTimestamp() {
        return this.deleteTimestamp;
    }

    public void setDeleteTimestamp(Date deleteTimestamp) {
        this.deleteTimestamp = deleteTimestamp;
    }
    public Date getDateCreated() {
        return this.dateCreated;
    }

    public void setDateCreated(Date dateCreated) {
        this.dateCreated = dateCreated;
    }
    public Date getLastUpdated() {
        return this.lastUpdated;
    }

    public void setLastUpdated(Date lastUpdated) {
        this.lastUpdated = lastUpdated;
    }

}

ProductCategory.java

public class ProductCategory  implements java.io.Serializable {


     private Integer idproductCategory;
     private String categoryName;
     private Date deleteTimestamp;
     private Date dateCreated;
     private Date lastUpdated;

    public ProductCategory() {
    }


    public ProductCategory(String categoryName, Date lastUpdated) {
        this.categoryName = categoryName;
        this.lastUpdated = lastUpdated;
    }
    public ProductCategory(String categoryName, Date deleteTimestamp, Date dateCreated, Date lastUpdated) {
       this.categoryName = categoryName;
       this.deleteTimestamp = deleteTimestamp;
       this.dateCreated = dateCreated;
       this.lastUpdated = lastUpdated;
    }

    public Integer getIdproductCategory() {
        return this.idproductCategory;
    }

    public void setIdproductCategory(Integer idproductCategory) {
        this.idproductCategory = idproductCategory;
    }
    public String getCategoryName() {
        return this.categoryName;
    }

    public void setCategoryName(String categoryName) {
        this.categoryName = categoryName;
    }
    public Date getDeleteTimestamp() {
        return this.deleteTimestamp;
    }

    public void setDeleteTimestamp(Date deleteTimestamp) {
        this.deleteTimestamp = deleteTimestamp;
    }
    public Date getDateCreated() {
        return this.dateCreated;
    }

    public void setDateCreated(Date dateCreated) {
        this.dateCreated = dateCreated;
    }
    public Date getLastUpdated() {
        return this.lastUpdated;
    }

    public void setLastUpdated(Date lastUpdated) {
        this.lastUpdated = lastUpdated;
    }

}

下面的代码是逻辑,它分为3部分。 REST层,Service层和DAO层。浏览器调用REST层,它将调用Service层,然后将调用DAO层。

剩余层代码

@POST
    @Path("/softDeleteProductByCategory")
    @Consumes(MediaType.APPLICATION_JSON)
    public Response softDeleteProductByCategory(ProductCategory category)
    {
        ProductService service= new ProductService();

        String result = service.softDeleteProductByCategory(category);
        return Response.status(Response.Status.OK).entity(result).build();
    }

服务层代码

public String softDeleteProductByCategory(ProductCategory category)
    {
        Session session = getSession();
        Transaction transaction = null;
        String result = "";

        try
        {
            transaction = getTransaction(session);

            pInterface.softDeleteProductByCategory(category.getIdproductCategory(), Common.getSQLCurrentTimeStamp(), session);
            transaction.commit();

            result = Common.SAVE_SUCCESS;

        }
        catch(Exception e)
        {
            e.printStackTrace();

            if(transaction!=null)
            {
                transaction.rollback();
                result = Common.SAVE_ROLLBACK;
            }
            else
            {
                result = Common.SAVE_ROLLBACK_FAILED;
            }
        }
        finally
        {
            session.close();
        }

        return result;
    }

DAO层代码

 @Override
    public void softDeleteProductByCategory(int categoryID, Timestamp deleteTime, Session session)
    {
        Query query = session.createQuery("UPDATE Product SET deleteTimestamp = :deleteTimestamp");
        query.setParameter("deleteTimestamp", deleteTime);
        query.executeUpdate();
    }

如果您有兴趣查看数据库图,请在下面。

enter image description here

问题是,当我执行上述代码时(当我叫/softDeleteProductByCategory时)出现以下错误。

19-Feb-2019 15:28:35.223 WARN [http-nio-8080-exec-300] org.hibernate.engine.jdbc.spi.SqlExceptionHelper.logExceptions SQL Error: 1205, SQLState: 40001
19-Feb-2019 15:28:35.224 ERROR [http-nio-8080-exec-300] org.hibernate.engine.jdbc.spi.SqlExceptionHelper.logExceptions Lock wait timeout exceeded; try restarting transaction
org.hibernate.exception.LockAcquisitionException: could not execute statement
    at org.hibernate.dialect.MySQLDialect$1.convert(MySQLDialect.java:451)
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:126)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:112)
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:190)
    at org.hibernate.hql.internal.ast.exec.BasicExecutor.doExecute(BasicExecutor.java:109)
    at org.hibernate.hql.internal.ast.exec.BasicExecutor.execute(BasicExecutor.java:78)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.executeUpdate(QueryTranslatorImpl.java:445)
    at org.hibernate.engine.query.spi.HQLQueryPlan.performExecuteUpdate(HQLQueryPlan.java:347)
    at org.hibernate.internal.SessionImpl.executeUpdate(SessionImpl.java:1282)
    at org.hibernate.internal.QueryImpl.executeUpdate(QueryImpl.java:118)
    at xx.xxx.api.dao.product.ProductDAOImpl.softDeleteProductByCategory(ProductDAOImpl.java:116)
    at xx.xxx.api.service.ProductService.softDeleteProductByCategory(ProductService.java:366)
    at xx.xxx.api.rest.ProductJSONService.softDeleteProductByCategory(ProductJSONService.java:94)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory.lambda$static$0(ResourceMethodInvocationHandlerFactory.java:76)
    at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:148)
    at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:191)
    at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:200)
    at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:103)
    at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:493)
    at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:415)
    at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:104)
    at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:277)
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:272)
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:268)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:316)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:298)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:268)
    at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:289)
    at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:256)
    at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:703)
    at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:416)
    at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:370)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:389)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:342)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:229)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:668)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:834)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1417)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Lock wait timeout exceeded; try restarting transaction
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:425)
    at com.mysql.jdbc.Util.getInstance(Util.java:408)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:952)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3978)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3914)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2530)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2683)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2495)
    at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1903)
    at com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2124)
    at com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2058)
    at com.mysql.jdbc.PreparedStatement.executeLargeUpdate(PreparedStatement.java:5158)
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2043)
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:187)
    ... 57 more

我该如何解决这个问题?

同时,我很确定我在这里使用了where子句,因此该语句就像UPDATE Product SET deleteTimestamp = :deleteTimestamp where productid= :id吗?

1 个答案:

答案 0 :(得分:0)

对于MySQL InnoDB,可以通过

解决-Lock wait timeout exceeded; try restarting transaction之类的错误
  1. 更改innodb_lock_wait_timeout的值。 参考-here
  2. 杀死线程锁定了表或处理时间太长。 参考-here
  3. 如果具有足够的特权,则检查InnoDB状态并确定阻止层次结构。 参考-here