2016-12-14 62 views
0

例如,我們有一個表(登錄,哈希)。我們在登錄列上沒有unique約束,但我們應該保持它的唯一性(例如)。 當新用戶註冊時,我們檢查輸入的登錄是否空閒。 如果這是一個部署到Tomcat的Java Web應用程序,它具有線程池,那麼這些檢查可能會並行處理,對吧?如何確保獨特性呢?沒有數據庫約束的獨特檢查

回答

1

您可以在表中使用悲觀鎖,這將鎖定表,並且您可以檢查是否存在,因此其他線程暫時無法更改該表。但我認爲這是一種非常糟糕的做事方式,爲什麼不使用數據庫約束?

1

簡而言之,在這裏沒有數據庫限制的情況下,你不能有一個好的解決方案。

在多線程環境中沒有約束條件,您需要一些公共資源來同步您的線程。一個線程會獲取互斥鎖,檢查登錄是否空閒(使用SELECT),然後INSERT是空閒的新記錄。沒有其他線程應該能夠同時做到這一點 - 這就是爲什麼你需要在這裏同步。

如果您的所有線程都可以訪問此互斥鎖,並且確保沒有其他人可以同時訪問數據庫,那麼這將起作用。

如果您有幾臺訪問相同數據庫的機器,則會出現第一個問題。在不同機器上運行的線程將無法訪問相同的互斥鎖,因此他們會很高興地並行插入表中。

另一個問題是,如果某人直接登錄到數據庫並直接在該表中創建記錄,那麼這種插入可能恰好發生在您的代碼執行的SELECT和INSERT之間。所以代碼中的同步在這裏沒有幫助。

另一種選擇是鎖定整個表格,但情況更糟。你需要非常可靠地釋放鎖定,否則你會冒着拖延整個系統的風險。