我有一個服務器應用程序和一個數據庫。服務器的多個實例可以同時運行,但所有數據都來自同一個數據庫(在某些服務器上是postgresql,在其他情況下是ms sql服務器)。數據庫記錄鎖定
在我的應用程序中,有一個過程需要幾個小時才能完成。我需要確保這個過程一次只能執行一次。如果一臺服務器正在處理,則其他服務器實例不能處理,直到第一個服務器實例完成。
該過程依賴於一個表(我們稱之爲'ProcessTable')。我所做的是,在任何服務器啓動長達一小時的過程之前,我在ProcessTable中設置一個布爾標誌,表示此記錄已被「鎖定」並正在處理中(並未處理/鎖定此表中的所有記錄,所以我需要專門標記過程所需的每條記錄)。因此,當下一個服務器實例出現而前一個實例仍在處理時,它會看到布爾標誌並引發異常。
問題是,兩個服務器實例可能幾乎同時被激活,並且當兩者都檢查ProcessTable時,可能沒有設置任何標誌,但兩個服務器實際上都在「設置」標誌,但由於事務尚未提交任一進程,因此這兩個進程都不會看到其他進程完成的鎖定。這是因爲鎖定機制本身可能需要幾秒鐘的時間,所以有兩個服務器仍然可以同時處理的機會窗口。
看來,我需要的是我的'設置'表中應該存儲一個名爲'LockInProgress'的布爾標誌的單個記錄。因此,在即使服務器可以鎖定ProcessTable中所需的記錄之前,首先必須通過檢查Settings表中的'LockInProgress'列來確保它具有完全鎖定權限。
所以我的問題是,如何防止兩個服務器同時修改設置表中的LockInProgress列......或者我以錯誤的方式解決這個問題?
請注意,我需要支持postgresql和MS SQL服務器,因爲有些服務器使用一個數據庫,而有些服務器使用另一個。
在此先感謝...
這是一個更好的主意,然後從Pradeep的答案,如果是這樣,爲什麼?看起來,這可能會起作用,但它似乎也有點複雜(可能更少一些「跨平臺」)......我可能是錯的...... – user85116 2010-02-25 19:01:31
您可能需要爲每個支持的平臺編寫不同的sproc ,但編寫某種插件機制以支持少數特定於平臺的操作並不困難。這種方法的關鍵在於它使用本地鎖定機制和語義(即一個進程被阻塞直到鎖定變爲空閒)。 – ConcernedOfTunbridgeWells 2010-02-26 07:29:16