zoukankan      html  css  js  c++  java
  • SQL检测超时工具类

    1.简述

      这个工具类主要是为了防止sql卡死或执行时间过长所编写的,这样做可以减少数据库占用资源,是使用定时器进行检测的。下面的案例我就没写定时器了,只是写了检测方法。该方法可以根据需求自己进行修改。

    2.实现

    /**测试类
     */
    public class Test{
        public static void main(String[] args) {
            SqlCheckUtils.checkSqlQueryTime();
        }
    }
    /**SQL检查工具类
     */
    class SqlCheckUtils {
        private static Log log = LogFactory.getLog(SqlCheckUtils.class);
        private static int recodeTime = 3;//超过该时间,则记录日志(单位:秒 )
        private static int killTime = 3;//超过该时间,则杀死语句(单位:秒 )
        private static String sql = "show full processlist";//查询哪些线程正在运行,注:Mysql是使用这条语句,其他数据库可更换
        
        public static void checkSqlQueryTime(){
            Connection con = getConnection();//获取数据库连接,这里是随便写的,可以换成自身项目使用的
            Statement st = null;
            ResultSet set = null;
            try {
                st = con.createStatement();
                set = st.executeQuery(sql);
                boolean isHave = false;
                while(set.next()){
                    int time = set.getString("time") != null ? Integer.parseInt(set.getString("time")) : 0;//持续的时间,单位是秒
                    String state = set.getString("state");//当前连接的sql语句的状态
                    if("Copying to tmp table".equalsIgnoreCase(state) //复制临时表
                            || "Writing to net".equalsIgnoreCase(state) //正在将数据包写入网络
                            || "Sending data".equalsIgnoreCase(state) //SQL正在处理 SELECT 查询
                            || "Sorting for group".equalsIgnoreCase(state) //SQL正在 GROUP BY 做排序
                            || "Sorting for order".equalsIgnoreCase(state)//SQL正在 ORDER BY 做排序
                            || "Sorting index".equalsIgnoreCase(state) //根据索引排序
                            || "Sorting result".equalsIgnoreCase(state) //创建索引
                            || "statistics".equalsIgnoreCase(state) //统计数据
                            || "Waiting for tables".equalsIgnoreCase(state)//数据表结构被修改了,需要重新打开数据表以取得新的结构。为了能的重新打开数据表,必须等到所有其他线程关闭这个表
                            || "Copying to tmp table on disk".equalsIgnoreCase(state)){//复制临时表,临时结果集大于tmp_table_size
                        
                        String id = set.getString("id");//标识,用于kill一个语句
                        if(time > killTime){//当前持续时间是否大于指定时间,是的话添加kill语句当前命令列表中
                            isHave = true;
                            st.addBatch("kill "+id);
                        }
                        if(time > recodeTime){//当前持续时间是否大于指定时间,是的话记录日志
                            String user = set.getString("user");//单前用户
                            String host = set.getString("host");//端口,可以知道是由哪个ip的哪个端口上发出的
                            String db = set.getString("db");//当前连接的是哪个数据库
                            String command = set.getString("command");//前连接的执行的命令,休眠(sleep)、查询(query)、连接 (connect)
                            String info = set.getString("info");//sql语句,因为长度有限,所以长的sql语句就显示不全
                            StringBuffer sb = new StringBuffer();
                            sb.append("database lock(>"+recodeTime+"): id(").append(id).append("), user(").append(user).append("), host(")
                                .append(host).append("), db(").append(db).append("), command(").append(command).append("), time(")
                                .append(time).append("), state(").append(state).append("), info(").append(info).append(")   ");
                            log.error(sb.toString());
                        }
                    }
                }
                set.close();
                if(isHave){//批量执行此列表中的命令
                    st.executeBatch();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }finally{
                close(set , st , con);//释放资源
            }
        }
        /**获取数据库连接
         */
        private static Connection getConnection(){
            Connection connection = null ;
            try {
                Class.forName("com.mysql.jdbc.Driver");
                String url = "jdbc:mysql://localhost:3306/mybatis?"+
                "zeroDateTimeBehavior=convertToNull&useSSL=false&useUnicode=true&characterEncoding=UTF-8";
                String user = "root" ;
                String pass = "123456" ;
                connection = DriverManager.getConnection(url, user, pass);
            } catch (Exception e) {
                log.error(e.getMessage());
                return null ;
            }
            return connection ;
        }
    
        /**释放资源
         */
        private static void close(ResultSet rs ,Statement st ,Connection ct){
            try {
                if(null != rs && !rs.isClosed()){
                    rs.close();
                }
            } catch (Exception e) {
                log.error(e.getMessage());
            }
    
            try {
                if(null != st && !st.isClosed()){
                    st.close();
                }
            } catch (Exception e) {
                log.error(e.getMessage());
            }
    
            try {
                if(null != ct && !ct.isClosed()){
                    ct.close();
                }
            } catch (Exception e) {
                log.error(e.getMessage());
            }
        }
    }
    View Code
  • 相关阅读:
    解决IE输入框文本输入时的 X
    CSS3发光输入框
    去掉超链接或按钮点击时出现的虚线边框
    [LeetCode][JavaScript]Add and Search Word
    [LeetCode][JavaScript]Lowest Common Ancestor of a Binary Search Tree
    [LeetCode][JavaScript]Palindrome Linked List
    [LeetCode][JavaScript]Number of Digit One
    [LeetCode][JavaScript]Implement Queue using Stacks
    [LeetCode][JavaScript]Implement Trie (Prefix Tree)
    [LeetCode][JavaScript]Power of Two
  • 原文地址:https://www.cnblogs.com/bl123/p/13752932.html
Copyright © 2011-2022 走看看