取消超时执行的sql

在线上 有些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);
            }

        }
    }
}

转载于:https://my.oschina.net/chinleon/blog/1606730

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值