spring定時任務quartz

2021-09-01 16:49:36 字數 1407 閱讀 5720

一般的定時任務是採用的quartz, quartz有兩種方式執行,第一種為普通的方式, 如果乙個任務每三分鐘執行一次,那麼前三分鐘的任務還沒執行完,後面的任務會繼續執行。這樣的壞處會導致兩個執行緒在同時處理一批資料,可能出現問題。

第二種方式是,如果乙個任務每三分鐘執行一次,那麼前三分鐘的任務還沒執行完,後面的任務會等待(執行緒等待),這樣會出現乙個長長的等待佇列,並且會建立很多的等待執行緒。

為了解決第二種方式的缺點,可以利用spring容器的特點。由於spring容器裡的類一般是單例的,也就是只有乙個例項,那麼可以寫如下的**:

class test 

}}

這樣當前乙個任務沒執行完時,這時isrunning 為true,後面的任務如果也開始執行,那麼由於是同乙個例項,所以isrunning也為true,if(!isrunning)條件不成立,所以結束。

但上面的**有乙個bug,那就是do some things時,如果出現異常isrunning將一直是true,後面的任務也不能執行。所以需要無論程式正常還是異常完成都設定 

isrunning=false。

這樣就實現了前一次沒執行完後面的任務不等待直接結束的效果。但這樣有乙個缺點,由於isrunning 是針對乙個容器可見的,也就是乙個虛擬機器jvm,所以當定時任務採用分布式處理時,一台電腦上的isrunning = true對另一台電腦來說是無效的。這時要採用的辦法就是將這個isrunning放入資料庫。

一般quartz有兩種方式,一種是ram方式,也就是記憶體方式。另外一種是資料庫方式,就是配置等資訊放入資料庫。很顯然,第一種方式在分布式環境下是無效的,因為一台電腦的定時任務配置只放在本機記憶體中,對其他電腦是不可見的。而資料庫方式是支援分布式處理的。資料庫處理時分布式的方式沒實踐過,但我覺得應該考慮併發 的問題,就是一條資料被兩個不同的電腦同時在處理的情況。前面說的將isrunning標示放入資料庫來判斷是一種解決辦法。但這樣有乙個缺點就是,對於同一任務,不能分布式的執行,即不能在電腦c1上執行a任務,又在一台電腦c2上執行a任務(但可以在一台電腦執行a b c任務,在另一台電腦執行 d e f任務)。當系統效能恰好在乙個定時任務上時,比如a任務處理量太大,必須在多個電腦上執行時,怎麼辦呢?

一般的定時任務都是取業務資料,執行一定邏輯,更新業務資料。那麼可以在取業務資料後立即將資料改變為執行中狀態,這樣另外乙個任務不會取到相同的業務資料來處理了。當執行完後,將執行中的狀態從資料庫去掉即可。這樣的方法增加了一定的**量,而且多增加了一些資料庫更新操作(更新業務資料的標誌)。相對於前面的單台電腦執行來說,要自己取捨。

另外的一種方式就是將任務拆分。比如任務處理的業務資料分為a b c d四類,那麼外面可以將任務拆分成四個,每台電腦執行其中的乙個即可。這種方式相對於上面一種來說,沒有多餘的資料庫更新操作,**量也少些。但缺點就是也許 a b c d四類資料分布不均,導致一台電腦很忙,另一台電腦很閒。

quart定時任務

在ssm專案裡面使用quart實現定時任務每10秒插入一條資料,使用xml配置方式實現。1.建立定時任務類 package com.tencent.tusi.test.quartztest import com.tencent.tusi.business.entity.tsystemusers im...

Spring定時任務

sayhello 0 08 21 下面的表示式 0 15 10 6l 2002 2005 將在2002年到2005年的每個月的最後乙個星期五上午10點15分執行作業。你不可能用 trigger來做這些事情。你可以用兩者之中的任何乙個,但哪個跟合適則取決於你的排程需要。更多詳細介紹參考此處 關於cro...

spring 定時任務

xmlns 多加下面的內容 xmlns task 然後xsi schemalocation多加下面的內容 spring task 3.1.xsd最後是我們的task任務掃瞄註解 或者 public inte ce imytestservice component import org.springf...