簡體   English   中英

數據庫記錄鎖定

[英]database record locking

我有一個服務器應用程序和一個數據庫。 服務器的多個實例可以同時運行,但所有數據都來自同一個數據庫(在某些服務器上是postgresql,在其他情況下是ms sql server)。

在我的應用程序中,執行的過程可能需要數小時。 我需要確保這個過程一次只執行一個。 如果一個服務器正在處理,則在第一個服務器實例完成之前,其他任何服

該過程取決於一個表(讓我們稱之為'ProcessTable')。 我所做的是,在任何服務器啟動長達一小時的過程之前,我在ProcessTable中設置一個布爾標志,表示該記錄被“鎖定”並正在處理(並非該表中的所有記錄都被處理/鎖定,所以我需要專門標記流程所需的每條記錄)。 因此,當前一個實例仍在處理時,當下一個服務器實例出現時,它會看到布爾標志並拋出異常。

問題是,兩個服務器實例可能幾乎同時被激活,並且當兩者都檢查ProcessTable時,可能沒有設置任何標志,但是兩個服務器實際上都在“設置”標志的過程中但是因為事務尚未提交任何一個進程,任何進程都不會看到其他進程完成鎖定。 這是因為鎖定機制本身可能需要幾秒鍾,因此存在兩個服務器可能仍然能夠同時處理的機會窗口。

看來我需要的是我的'Settings'表中的一條記錄,它應該存儲一個名為'LockInProgress'的布爾標志。 因此,即使服務器可以鎖定ProcessTable中所需的記錄,它首先必須通過檢查Settings表中的'LockInProgress'列來確保它具有完全的權限來進行鎖定。

所以我的問題是,如何阻止兩台服務器同時修改設置表中的LockInProgress列?或者我是否以錯誤的方式處理此問題?

請注意,我需要支持postgresql和ms sql server,因為有些服務器使用一個數據庫,而有些服務器使用另一個。

提前致謝...

如何首先獲取記錄鎖定然后更新記錄以顯示“已鎖定”。 這將避免第二個實例成功獲得鎖定,從而更新記錄失敗。

重點是確保鎖定並更新為一個原子步驟。

創建一個存儲過程來解鎖,並在“可序列化”隔離下運行它。 這將保證在任何給定時間只有一個進程可以獲取資源。

請注意,這意味着嘗試獲取鎖定的第二個進程將阻塞,直到第一個進程釋放它。 此外,如果您必須以這種方式獲得多個鎖,請確保該過程的設計保證將以相同的順序獲取和釋放鎖。 這將避免死鎖情況,其中兩個進程在等待彼​​此釋放鎖時保持資源。

除非你不能處理你的其他進程阻塞,否則這可能比試圖實現'test and set'語義更容易實現和更強大。

我一直在考慮這個問題,我認為這是最簡單的做事方式; 我只是執行這樣的命令:

update settings set settingsValue = '333' where settingsKey = 'ProcessLock' and settingsValue = '0'

'333'將是每個服務器進程獲得的唯一值(基於日期/時間,服務器名稱,+隨機值等)。

如果沒有其他進程鎖定表,則settingsValue將= = 0,該語句將調整settingsValue。

如果另一個進程已經鎖定了該表,那么該語句將成為無操作,並且沒有任何內容被修改。

然后我立即提交交易。

最后,我重新查詢表的settingsValue,如果它是正確的值,那么我們的鎖成功,我們繼續,否則拋出異常,等等。當我們完成鎖定后,我們將值重新設置為到0。

由於我正在使用SERIALIZATION交易模式,我無法看到這導致任何問題...如果我錯了請糾正我。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM