【问题标题】:Hibernate:LockAcquisitionException when trying to update尝试更新时出现休眠:LockAcquisitionException
【发布时间】:2019-07-12 19:24:21
【问题描述】:

我有 2 张桌子,ProductProductCategoryProduct 表的外键为ProductCategory

我正在构建一个 REST API,我正在尝试删除 ProductCategoryProducts。我正在使用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();
    }

如果你有兴趣看数据库图,下面是。

问题是,当我执行上面的代码时(当我调用/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

【问题讨论】:

  • 在 Dao 中的 softDeleteProductByCategory() 中的查询没有你最后提到的 where 子句。对吗?
  • @PriyankaW:不管有没有where 子句,错误都不应该出现。
  • 当需要处理的数据过多时,出错的可能性会增加。 where 子句减少了要处理的记录数,所以我认为这可能会解决问题。你使用过 InnoDB 存储引擎和 READ-COMMITTED 事务隔离级别吗?还是您有其他设置?

标签: java mysql hibernate rest hql


【解决方案1】:

在 MySQL InnoDB 的情况下,类似 - Lock wait timeout exceeded; try restarting transaction 的错误可以通过

解决
  1. 更改innodb_lock_wait_timeout 值。 参考 - here
  2. 正在杀死锁定表或处理时间过长的线程。 参考 - here
  3. 如果有足够的权限,则检查 InnoDB 状态并识别阻塞层次结构。 参考 - here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-02
    • 1970-01-01
    • 1970-01-01
    • 2012-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多