2010-03-08 43 views
0

我有一個由SQL服務器作業觸發的java JAR文件。它已經運行了好幾個月。該過程將結構化的平面文件引入暫存數據庫,然後將該數據推送到XML文件中。如何處理產生兩個本身的Java程序?

但是昨天這個過程同時被觸發了兩次。我可以從創建的日誌文件中看出,它看起來像是同時運行了兩次。這導致了很多問題,它踢出來的XML文件格式不正確,幷包含重複節點等。

我的問題是,這是Java JVM產生自身的多個實例的已知問題嗎?或者我應該將sql server視爲罪魁禍首?我正在研究'套接字鎖定'或文件鎖定以防止將來出現多個實例。

這是我聽說過的這個問題的第一個例子。

更多信息:

作業計劃爲每分鐘運行。 作業觸發包含java.exe的.bat文件 - jar filename.jar

java程序運行時,掃描目錄中的文件,然後執行循環以處理文件是否找到。處理文件後,它會運行另一個循環來啓動XML消息。

我可以提供代碼示例,如果這將有所幫助。

謝謝

凱文

+0

請參閱http://stackoverflow.com/questions/177189/how-to-implement-a-single-instance-java-application – RichardOD 2010-03-08 15:57:58

+0

聽起來像昨天是該過程花費了一分多鐘才完成的第一次。由於它尚未做到將數據標記爲已處理的數據,一分鐘後開始的二次數據認爲它有工作要做。以下建議的鎖定解決方案應該可以幫助您永久解決問題。作爲臨時解決方案,將作業之間的時間增加到5或10分鐘。 – 2010-03-08 17:44:52

+0

克里斯,感謝您的意見。 這是我對Sql-Server作業的理解,它會等到作業完成再開始之前。它在一小時內運行1分鐘,所以如果它在05:01:00運行並且運行到05:02:25它將等到05:03:00再次運行。 我打算讓我們列出解決問題的解決方案之一。我希望能更好地理解這個問題。我寫了很多這樣的過程,這是我第一次看到這個問題。 – kevingreen 2010-03-08 18:24:03

回答

3

這不是一個Java問題。如果您希望應用程序獨立運行,不需要副本,則應該使用shell腳本或java應用程序在某處創建和刪除鎖定。

你其實開始多個Java的通過使用相同的命令啓動多個批處理作業。 Windows和Java現在都不是你想要的。你可以通過類似的方式解決:

public static void main(String [ ] args) 
{ 
    createLockIfNotExists(); 
    try { 
     yourstuff; 
    } finally { 
    releaseLock(); 
    } 
} 
private static void createLockIfNotExists() throws MyLockAlreadyExists { 
    // A bit tricky 
    // check if LOCKFILE exists, if yes throw MyLockAlreadyExists 
    // try to create LOCKFILE, can fail if at 1 ms earlier an other app created 
    // that file, so an exception while creating also results in LockAlreadyExists 
} 

是否有很好的例子來處理這種鎖定?也許在Apache Commons中?

Here似乎是Windows的一個運行示例。

你也可以使用數據庫來寫你的鎖。當然,在使用鎖定表之前先鎖定鎖定表,這樣不會有2個進程同時寫入它們的鎖,然後讀取鎖定記錄以檢查是否真的獲得了鎖。像僞代碼:

SELECT * FROM lock_table; 

if locks.length > 0: someone else is running 

LOCK lock_table; 
INSERT INTO lock_table VALUES(my_pid); 
UNLOCK lock_table; 

SELECT pid FROM lock_table; 

if pids.length > 1: what happened? 
if pids[0] != my_pid: someone else got the lock 

多一點的果汁,你也不僅增加了PID也是一個時間戳,並檢查時間戳是否是陳舊的(太舊)。

+0

謝謝Richard和Extaneon。我將嘗試實現Richard鏈接到的文章中引用的套接字鎖定連接。 如果套接字方法不起作用,我可能會嘗試Lockfile技術。 我最擔心的是我有幾個進程通過執行Java的SQL服務器作業運行。如果我也有,我會爲所有這些創建鎖定進程,但我仍然想知道是什麼原因造成了這個問題。 我的理解是,它只能通過sql server作業運行一次。但我可能會錯過一些東西。 謝謝! – kevingreen 2010-03-08 16:07:53

+0

我也應該提到,我會投票你的答案,但我還不能。我不知道你是否關心這些問題,但如果可以的話,我會給予他們。 – kevingreen 2010-03-08 16:09:11

+0

我同意,如果兩個實例在不同的JVM上運行,則需要使用文件的存在來鎖定資源。 Linux/UNIX上的標準做法是將進程標識放在該文件中,以便人員可以更輕鬆地找到該進程。 – 2010-03-08 16:12:06

相關問題