近日,在項目中使用Strtus1.2+Spring 3.0.6+Hibernate 3.3.2,搭建一個小業務系統,有定時執行某些任務的需要,並且涉及到資料庫操作,不經意間發現spring3.0新增了一個內建的調度任務,使用方式與quartz類似,而且功能也差不多,所以嘗試著使用此功能。
剛開始,使用間隔的形式,每次任務都執行2次,一開始以為是這個間隔不是很精確造成的,後來在上線前的測試中發現,要求每周一淩晨3點執行的任務,結果一下執行2次,導致很多重複資料。
不斷調整cron運算式,問題依舊。
不斷Google、baidu,總是找不到類似問題,但是,在一篇介紹spring3調度任務的文章中,提到老外們發現的一個bug,就是使用基於標記的調度任務時,任務每次會執行2次,而且spring官網已經將這個bug規划到3.2版本解決。但是,我使用的不是基於標記而是基於配置的調度任務,用E文關鍵字搜尋一下,發現確實有類似情況,不過人家說是由於spring設定檔被多次載入造成的,多數是由於web.xml中配了spring的監聽,又配置了spring的servlet造成的,但是我的web.xml比較正常,沒有類似問題。
但是,由於action採用spring管理的模式,因此,在struts的設定檔中
<plug-in className="org.springframework.web.struts.ContextLoaderPlugIn"><set-property property="contextConfigLocation" value="/WEB-INF/applicationContext.xml" /></plug-in>
而applicationContext.xml檔案中有以下內容
<import resource="action-config.xml" /><import resource="springTasks.xml" />
相當於applicationContext.xml檔案把所有的相關配置都載入進來。而在web.xml裡面
<listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener>
已經載入過一次applicationContext.xml,這樣,相當於applicationContext.xml被載入兩次,因此,涉及到調度任務的部分自然就會被執行兩次。
解決辦法很簡答,由於之前已經把與struts相關的部分bean的配置單獨拿出來放在action-config.xml檔案中了,因此,直接修改struts-config.xml檔案中ContextLoederPlugIn的部分為以下內容
<plug-in className="org.springframework.web.struts.ContextLoaderPlugIn"><set-property property="contextConfigLocation" value="/WEB-INF/action-config.xml" /></plug-in>
重新啟動應用,問題解決!