程序问答   发布时间:2022-06-02  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了自动终止长时间运行的查询(MySql),Apache Tomcat数据源大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如何解决自动终止长时间运行的查询(MySql),Apache tomcat数据源?

开发过程中遇到自动终止长时间运行的查询(MySql),Apache tomcat数据源的问题如何解决?下面主要结合日常开发的经验,给出你关于自动终止长时间运行的查询(MySql),Apache tomcat数据源的解决方法建议,希望对你解决自动终止长时间运行的查询(MySql),Apache tomcat数据源有所启发或帮助;

该答案适用于Apache tomcat-jdbc数据源提供程序。

首先,您需要了解PoolPropertIEs

  1. setRemoveAbandonedTimeout

  2. setRemoveAbandoned

当查询花费的时间超过setRemoveAbandonedTimeout(int)中指定的时间时,执行此查询的连接将标记为Abandon,并调用java.sql.Connection.close()方法,它将在释放连接之前一直等待查询完成。 。

我们可以实现自己的处理程序来处理废弃的连接。以下是变化

首先我们需要添加一个接口

package org.apache.tomcat.jdbc.pool;

public interface AbandonedConnectionHandler {

        public voID handlequery(Long connectionID);

}

tomcat-jdbc文件更改:

(接口)

添加getter和setter方法。

public voID setAbandonedConnectionHandler(AbandonedConnectionHandler  abandonedConnectionHandler);

public AbandonedConnectionHandler getAbandonedConnectionHandler();

将这些方法覆盖到所有实现类

  • DatasourceProxy.java
  • PoolPropertIEs.java
  • org.apache.tomcat.jdbc.pool.jmx.ConnectionPool.java

将方法 添加到

public Long getConnectionID() {
    try {
        //jdbc impl has getID()
        Method method = this.connection.getClass().getSuperclass().getmethod("getID");
        return (Long)method.invoke(this.connection);
    } catch (Exception E) {
        log.warn(" Abandoned queryHandler Failed to initialize connection ID ");
    }
    return null;
}

在使用不同的MysqL驱动程序的情况下,上述反射代码可能会有所不同。

现在我们需要在org.apache.tomcat.jdbc.pool.ConnectionPool.java中调用java.sql.Connection.close()方法之前放置处理程序。

将启动废弃的连接清除程序的ConnectionPool.java方法是

protected voID abandon(PooledConnection con)

在调用 之前,在此方法内添加以下代码

if(getPoolPropertIEs().getAbandonedConnectionHandler() != null)
            {
                con.lock();
                getPoolPropertIEs().getAbandonedConnectionHandler().handlequery(con.getConnectionID());
            }

现在,您要做的就是在创建tomcat-jdbc数据源时将handerInstance与PoolPropertIEs一起传递。

p.setAbandonedConnectionHandler(new ConnectionHandler(true));

这是我的AbandonedConnectionHandler实现。

import java.sql.Connection;
import java.sql.DriveRMANager;
import java.sql.ResultSet;
import java.sql.sqlException;
import java.sql.Statement;

import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.jdbc.pool.AbandonedConnectionHandler;
import org.apache.tomcat.jdbc.pool.PoolConfiguration;


public class ConnectionHandler implements AbandonedConnectionHandler{

    private static final Log log = LogFactory.getLog(ConnectionHandler.class);

    private Boolean isAllowedToKill;    
    private PoolConfiguration poolPropertIEs;

    public ConnectionHandler(Boolean isAllowedToKill)
    {
        this.isAllowedToKill = isAllowedToKill;
    }

    @OverrIDe
    public voID handlequery(Long connectionID) {
        Connection conn = null;
        Statement stmt = null;
        if(this.isAllowedToKill)
        {
            try{

                Class.forname(poolPropertIEs.getDriverClassname());
                conn = DriveRMANager.getConnection(poolPropertIEs.getUrl(),poolPropertIEs.getUsername(),poolPropertIEs.getpassword());

                Statement statement = conn.createStatement();
                ResultSet result = statement.executequery("SELECT ID, INFO, USER, TIME FROM information_scheR_246_11845@a.PROCESSList WHERE ID=" + connectionID);

                if(result.next())
                {   
                    if(isFetchquery(result.getString(2)))
                    {
                        statement.execute("Kill "+connectionID);
                    }

                }
                statement.close();
                conn.close();
            }
            catch(Exception E)
            {
                e.printstacktrace();
            }
            finally
            {
                try {
                    if(stmt != null && !stmt.isClosed())
                    stmt.close();
                } catch (sqlException E) {
                    log.warn("Exception while closing Statement ");
                }
                try {
                    if(conn != null && !conn.isClosed() )
                    conn.close();
                } catch (sqlException E) {
                    log.warn("Exception while closing Connection ");
                }
            }
        }
    }
    private Boolean isFetchquery(String query)
    {
        if(query == null)
        {
            return true;
        }
        query = query.trim();
        return "SELECT".equalsIgnoreCase(query.subString(0, query.indexOf(' '))); 
    }

    public PoolConfiguration getPoolPropertIEs() {
        return poolPropertIEs;
    }
    public voID setPoolPropertIEs(PoolConfiguration poolPropertIEs) {
        this.poolPropertIEs = poolPropertIEs;
    }

}

解决方法

我们的Java Web应用程序具有搜索功能,允许用户搜索大型数据库中的记录。

如果用户指定了错误的搜索参数,那么它们将以无法结束的查询结束,因为该查询需要运行几个小时。

这是一个Web应用程序,因此他们反复尝试,查询阻塞了所有资源,从而导致严重的性能问题。

如果查询运行时间太长或使用了过多的CPU,是否可以自动终止查询?

大佬总结

以上是大佬教程为你收集整理的自动终止长时间运行的查询(MySql),Apache Tomcat数据源全部内容,希望文章能够帮你解决自动终止长时间运行的查询(MySql),Apache Tomcat数据源所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。