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