取消超时执行的sql

强颜欢笑 提交于 2020-03-01 19:49:48

在线上 有些sql执行的比较慢,希望可以指定超时时间, 取消这个sql的执行,以下以druid为例为实现这个功能

jdbc 有2个超时时间, 一个是queryTimeout, 一个是socketTimeout,
queryTimeout的作用是sql执行超时之后,可以取消这次的执行,底层原理是发送kill $id通知mysql来中断这个sql的执行
socketTimeout的作用主要是为了解决tcp连接超时的问题, 超时之后,这个tcp连接会断开

要注意的是,socket超时只是释放tcp链接, 但sql还是在mysql里面执行(可以通过show processlist来看到)

所以为了取消sql的执行,socketTimeout的时间一定要大于queryTimeout才有意义


queryTimeout会抛出异常com.mysql.jdbc.exceptions.MySQLTimeoutException: Statement cancelled due to timeout or client request

socketTimeout会抛出异常com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

The last packet successfully received from the server was 2,020 milliseconds ago. The last packet sent successfully to the server was 2,010 milliseconds ago.

可以看具体示例

public class JdbcTimeout {

    DruidDataSource dataSource = new DruidDataSource();

    @Before
    public void setUp() {
        dataSource.setUsername("root");
        dataSource.setPassword("123456");
        dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/case?useUnicode=true&characterEncoding=utf-8&socketTimeout=20000000");
        dataSource.setQueryTimeout(5);
        System.out.println("started");
    }
    @Test
    public void testQuery() throws Exception {
        try(Connection conn = dataSource.getConnection() ) {
            try(Statement stmt = conn.createStatement()) {
                String sql = "SELECT sleep(30*1000), 'name' ";
                try(ResultSet rs = stmt.executeQuery(sql)) {
                    while (rs.next()) {
                        String name = rs.getString("name");
                        System.out.println(name);
                    }
                }

            }

        }

    }
    @Test
    public void testUpdate() throws Exception {
        String sql = "UPDATE person  SET age=3  WHERE id=1 AND SLEEP(30*1000)";
        try(Connection conn = dataSource.getConnection() ) {
            try(Statement stmt = conn.createStatement()) {
                int updated = stmt.executeUpdate(sql);
                System.out.println(updated);
            }

        }
    }
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!