Java Hibernate:尝试更新时发生LockAcquisitionException

Java Hibernate:尝试更新时发生LockAcquisitionException,java,mysql,hibernate,rest,hql,Java,Mysql,Hibernate,Rest,Hql,我有两个表,Product和ProductCategory。Product表的外键为ProductCategory 我正在构建一个RESTAPI,并试图通过ProductCategory删除Products。我使用的是Hibernate,我的数据库是MySQL 请检查下面的代码 Product.java public class Product implements java.io.Serializable { private Integer idproduct; pr

我有两个表,
Product
ProductCategory
Product
表的外键为
ProductCategory

我正在构建一个RESTAPI,并试图通过
ProductCategory
删除
Product
s。我使用的是
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;
    }

}
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;
    }

}
ProductCategory.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;
    }

}
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个部分<代码>休息层、
服务
层和
DAO
层。浏览器调用
REST
层,它将调用
服务
层,这将调用
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;
    }
 @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();
    }
服务层代码

@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;
    }
 @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();
    }
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;
    }
 @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
子句,因此该语句类似于
updateproductsetdeletetetetistamp=:deletetistamp where productid=:id

在MySQL InnoDB的情况下,超出了类似-
锁等待超时的错误;尝试重新启动事务
可以通过

  • 更改innodb锁定等待超时值。 参考-
  • 正在终止锁定表的线程或处理时间过长。 参考-
  • 如果有足够的权限,则检查InnoDB状态并确定阻塞层次结构。 参考-

  • 在MySQL InnoDB的情况下,超过了-
    锁等待超时等错误;尝试重新启动事务
    可以通过

  • 更改innodb锁定等待超时值。 参考-
  • 正在终止锁定表的线程或处理时间过长。 参考-
  • 如果有足够的权限,则检查InnoDB状态并确定阻塞层次结构。 参考-

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