取消超时执行的sql

在线上 有些sql执行的比较慢,但愿能够指定超时时间, 取消这个sql的执行,如下以druid为例为实现这个功能java

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 requestmysql

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

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.socket

能够看具体示例tcp

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);
            }

        }
    }
}
相关文章
相关标签/搜索