取消超時執行的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);
            }

        }
    }
}
相關文章
相關標籤/搜索