Mysql cancel分析

最近看了下mysql jdbc的cancel功能的源码,做个笔记记录下

Jdbc:mysql-connector-java-8.0.18.jar

 

mysql-connector源码中有个CancelQueryTask(CancelQueryTaskImpl)定时任务,CancelQueryTaskImpl继承了TimerTask同时实现了CancelQueryTask接口。


在ClientPreparedStatement.executeInternal方法里面会通过this.startQueryTimer()方法去生成这个CancelQueryTask

CancelQueryTask这个对象是用于将执行中的SQL取消掉的任务对象,当SQL执行前,通过StatementImpl.setQueryTimeout(int)(参数单位为秒)这个参数的值只要不是0,

它就会在JDBC内部与MySQL通信前会创建一个任务(当前connection新建一个CancelQueryTaskImpl对象)并设置延迟执行的时间(timeout的时间),

然后会将这个任务放入到一个Timer的任务队列中,等待触发执行。如果是0就会返回null(CancelQueryTask为null)

cancel任务:

run方法里面会新建一个SocketConnection
然后通过NativeSession.sendCommand()发送消息来做cancel的操作
发送kill query命令,同时标记状态
后面会通过localQueryToCancel.setCancelStatus(CancelStatus.CANCELED_BY_TIMEOUT);对当前TimerTask任务中的Query对象,将CancelStatus设置为TIMEOUT。

这就是一次因为timeout而做的cancel。

1.主动cancel

调用StatementImpl.cancel()方法在获取一些本地信息后会新建一个SocketConnection
然后通过NativeSession.sendCommand()发送消息来做cancel的操作发送kill query命令,同时标记状态
后面也会通过localQueryToCancel.setCancelStatus(CancelStatus.CANCELED_BY_USER); 对当前TimerTask任务中的Query对象,将CancelStatus设置为.CANCELED_BY_USER。

2.被动cancel
当执行完execSQL以后
如果CancelQueryTask不为null,SQL语句一直未响应,CancelQueryTask在达到设置的timeout值时会被Timer调度
会执行stopQueryTimer()方法内部去调用CancelQueryTask.cancel();此时的timeoutTask.cancel()并不是真正的去执行cancel操作,

只是将state设置为了CANCELLED仅仅对状态做了标记而已,后面的purge()方法,发现状态为取消,会去真正移除该任务

在从Timer的任务队列将CancelQueryTask任务cancel掉,然后从此Timer的任务队列中删除所有已取消的任务

猜你喜欢

转载自blog.csdn.net/qq_40210804/article/details/111562918
今日推荐