この回答はApache Tomcat-jdbc DataSource providerについてのものです。
クエリが長くsetRemoveAbandonedTimeout(int型)で指定した時間よりもかかったときPoolProperties
setRemoveAbandonedTimeout
の理解が
をsetRemoveAbandoned持っている必要があり、すべての
ファーストこのクエリを実行する接続はAbandonとマークされ、java.sql.Connection.close()メソッドが呼び出されます。 pは、接続を解放する前にクエリが完了するのを待っています。
放棄された接続を処理する独自のハンドラを実装できます。
PoolConfiguration.java(インターフェース)
ゲッターの追加と:以下はインタフェースに
package org.apache.tomcat.jdbc.pool;
public interface AbandonedConnectionHandler {
public void handleQuery(Long connectionId);
}
のtomcat-JDBCファイルの変更を追加するために必要なすべての
最初に変更がありますセッターメソッド。
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)
はリリース(CON)を呼び出す前に、このメソッド内のコードの下に追加され、今
if(getPoolProperties().getAbandonedConnectionHandler() != null)
{
con.lock();
getPoolProperties().getAbandonedConnectionHandler().handleQuery(con.getConnectionId());
}
あなたがしなければならないすべては、Tomcat-JDBCデータソースを作成中PoolPropertiesと一緒にあなたのhanderInstanceを渡すことです。
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;
}
}
https://stackoverflow.com/questions/18253934/set-maximum-execution-time-in-mysql-php – user7294900