栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

自动终止长时间运行的查询(MySql),Apache Tomcat数据源

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

自动终止长时间运行的查询(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文件更改:

PoolConfiguration.java (接口)

添加getter和setter方法。

public void setAbandonedConnectionHandler(AbandonedConnectionHandler  abandonedConnectionHandler);public AbandonedConnectionHandler getAbandonedConnectionHandler();

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

  • DataSourceProxy.java
  • PoolProperties.java
  • org.apache.tomcat.jdbc.pool.jmx.ConnectionPool.java

将方法 getConnectionId() 添加到
org.apache.tomcat.jdbc.pool.PooledConnection.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)

在调用 release(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_schema.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;    }}


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/636014.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号