下面我们就开始试试把derby换成H2,C3P0换成Hikari,把不想支持的derby和c3p0相关代码删掉,顺便阅读部分源码。
替换Derby为H2
搜索所有derby相关的代码,用H2替换,注:区别在于H2的mem是默认在connection close时候关掉数据库的,要加个;DB_CLOSE_DELAY=-1到connection url后面,不然刚创建的表,connection close就全丢失了。
H2的Server类可以用来替换DerbyServer。
H2无法像DerbyServer一样有专门的shutdown方法,可以使用connection.createStatement().execute("SHUTDOWN");代替。
修改完后,跑测试,FlakyJdbcSchedulerTest是唯一一个失败的,失败原因是重复的scheduler name,问题应该是数据库没清空,原因是destroyDatabase的时候包异常了,fix就完事儿了。
总结就是Derby比H2更适合测试各种关停重启数据库丢失数据的测试用例,同样的代码H2还会时不时的报一些NPE,莫名其妙。
删掉C3P0,默认使用HIKARI。
所有测试跑通过,其中JdbcSchedulerTest,可以帮助阅读Job,Trigger,Scheduler相关代码,通过逐个对test case使用理解,慢慢理解源码各个方法的用处以及原理。StdRowLockSemaphoreTest帮助理解排他锁的用法。
到这里,经过反复的修改,阅读,测试,大体流程已经了解,QuartzSchedulerThread无限循环,当有availWorkThread的时候,就通过JobStore查找Trigger,Trigger里包含了Job的Key,就可以找到Job,JobStore通过Trigger生成TriggerFireResult,然后用JobRunShellFactory创建JobRunShell并传入TriggerFiredResult,这里JobRunShell已经包含了Job所需的任何信息,所以最后把JobRunShell丢进ThreadPool,另起一个线程运行。