Mysql cancel分析
最近看了下mysql jdbc的cancel功能的源碼,做個筆記記錄下
Jdbc:mysql-connector-java-8.0.18.jar
?
mysql-connector源碼中有個CancelQueryTask(CancelQueryTaskImpl)定時任務,CancelQueryTaskImpl繼承了TimerTask同時實現(xiàn)了CancelQueryTask接口。
在ClientPreparedStatement.executeInternal方法里面會通過this.startQueryTimer()方法去生成這個CancelQueryTask
CancelQueryTask這個對象是用于將執(zhí)行中的SQL取消掉的任務對象,當SQL執(zhí)行前,通過StatementImpl.setQueryTimeout(int)(參數(shù)單位為秒)這個參數(shù)的值只要不是0,
它就會在JDBC內部與MySQL通信前會創(chuàng)建一個任務(當前connection新建一個CancelQueryTaskImpl對象)并設置延遲執(zhí)行的時間(timeout的時間),
然后會將這個任務放入到一個Timer的任務隊列中,等待觸發(fā)執(zhí)行。如果是0就會返回null(CancelQueryTask為null)
cancel任務:
run方法里面會新建一個SocketConnection
然后通過NativeSession.sendCommand()發(fā)送消息來做cancel的操作發(fā)送kill query命令,同時標記狀態(tài)。
后面會通過localQueryToCancel.setCancelStatus(CancelStatus.CANCELED_BY_TIMEOUT);對當前TimerTask任務中的Query對象,將CancelStatus設置為TIMEOUT。
這就是一次因為timeout而做的cancel。
?
1.主動cancel
調用StatementImpl.cancel()方法在獲取一些本地信息后會新建一個SocketConnection
然后通過NativeSession.sendCommand()發(fā)送消息來做cancel的操作發(fā)送kill query命令,同時標記狀態(tài)。
后面也會通過localQueryToCancel.setCancelStatus(CancelStatus.CANCELED_BY_USER); 對當前TimerTask任務中的Query對象,將CancelStatus設置為.CANCELED_BY_USER。
2.被動cancel
當執(zhí)行完execSQL以后
如果CancelQueryTask不為null,SQL語句一直未響應,CancelQueryTask在達到設置的timeout值時會被Timer調度
會執(zhí)行stopQueryTimer()方法內部去調用CancelQueryTask.cancel();此時的timeoutTask.cancel()并不是真正的去執(zhí)行cancel操作,
只是將state設置為了CANCELLED僅僅對狀態(tài)做了標記而已,后面的purge()方法,發(fā)現(xiàn)狀態(tài)為取消,會去真正移除該任務。
在從Timer的任務隊列將CancelQueryTask任務cancel掉,然后從此Timer的任務隊列中刪除所有已取消的任務。
總結
以上是生活随笔為你收集整理的Mysql cancel分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Robosense速腾激光雷达如何录制与
- 下一篇: QuickBooks2020中文版