5台裝置分布式處理30項任務,在30項任務全部處理完成時發送郵件通知,需要在最後一個任務完成時觸發郵件發送動作,實作方式:
1、程式中實作,在程式中synchronized變量表示剩餘任務數;
2、編寫觸發器?相容多資料庫比較麻煩;
3、利用資料庫在程式中判斷,行級鎖保證資料準确性;
1)每次更新已完成任務數後查詢剩餘的任務數,為0時表示任務完成,每個任務需要查詢一次;
2)利用update語句執行成功時傳回更新記錄數,特意讓最後一次更新記錄數為0(不成功),以下為模拟代碼:
/** 處理每個任務,finished為true表示最後一個任務 */
public static int doTask(boolean finished)
{
int result = 0;// 執行update語句更新資料庫總記錄數
Connection conn = null;
PreparedStatement stmt = null;
try {
conn = DriverManager.getConnection(
"jdbc:oracle:thin:@192.168.100.2:1521:orcl",
"h2do", "h2do");
if(!finished){
//
// TODO:處理其他資料
// 先送出,減少更新完成任務數的鎖定時間
conn.commit();
}
/* 條件finished=total-1時表示最後一個任務,<total-1時才能更新成功,最後一個任務更新失敗 */
stmt = conn.prepareStatement(
"update t_progress set finished = finished + 1 where id = ? and finished < total - ?");
stmt.setInt(1, 1);
stmt.setInt(2, finished ? 0 : 1);
result = stmt.executeUpdate();
/*
* 也可在這裡select total-finished from t_progress where id = 1
* 根據未完成數判斷是否所有任務均已完成
*/
conn.commit();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {if (null != stmt)stmt.close();} catch (Exception e) {}
try {if (null != conn)conn.close();} catch (Exception e) {}
}
return result;
}
public static void main(String[] args) throws Throwable
{
oracle.jdbc.driver.OracleDriver.class.newInstance();
/*模拟30個任務并發處理*/
for (int i = 0; i < 30; i++)
{
new Thread(new Runnable() {
@Override
public void run() {
int result = doTask(false);
if (0 == result) {
result = doTask(true);
if(1 == result){
System.out.println("發送所有任務完成郵件。。。");
}else{
//TODO:記錄日志;
}
}
}
}).start();
}
}
附:
create table t_progress
(
id integer not null,
total integer not null,
finished integer default 0 not null,
constraint pk_t_progress primary key (id)
);
insert into t_progress (ID, TOTAL, FINISHED) values (1, 30, 0);
版權聲明:本文為CSDN部落客「weixin_34292959」的原創文章,遵循CC 4.0 BY-SA版權協定,轉載請附上原文出處連結及本聲明。
原文連結:https://blog.csdn.net/weixin_34292959/article/details/91594247