我有一個Web應用程序,我使用的Oracle數據庫和我基本上是這樣的方法上:Java線程鎖定特定對象
public static void saveSomethingImportantToDataBase(Object theObjectIwantToSave) {
if (!methodThatChecksThatObjectAlreadyExists) {
storemyObject() //pseudo code
}
// Have to do a lot other saving stuff, because it either saves everything or nothing
commit() // pseudo code to actually commit all my changes to the database.
}
現在沒有任何一種這樣的同步N個線程當然這個方法可以自由地訪問,當兩個線程進入這個方法時,問題就出現了,當然這個方法沒有任何東西,然後他們都可以提交事務,創建一個重複的對象。
我不想用我的數據庫中唯一的密鑰標識符來解決這個問題,因爲我不認爲我應該抓住那個SQLException
。
我也不能在提交前檢查,因爲有幾個檢查不僅1
,這將花費相當多的時間。
我對鎖和線程的使用經驗有限,但我的想法基本上是將此代碼鎖定在它正在接收的對象上。我不知道是否例如說我收到一個Integer對象,並且我使用值1鎖定Integer,是否僅阻止其他具有值1的Integer的線程進入,並且所有其他具有value != 1
的線程都可以自由輸入? ,這是如何工作的?
此外,如果這是它的工作原理,鎖定對象是如何比較的?它如何確定它們實際上是同一個對象?關於這一點的好文章也將不勝感激。
你會如何解決這個問題?
爲什麼你不覺得你應該捕捉SQL異常? Oracle內置了幾十年來由非常聰明的人開發的功能,每天都有數以萬計的已安裝用戶使用,可以解決您的問題。他們的輪子工作正常。只要你的應用程序變得足夠大,需要進行集羣,你就會討厭這種內存鎖定。 – Affe
@Affe該應用程序實際上已經在tomcat集羣中,所以是的,我擔心線程鎖定的原因...我想捕捉SQL異常會工作,我只是想看到其他的可能性,捕捉的東西SQL例外是,我將不得不檢查它是正確的ORA號碼,如果有的話,這是否經常改變? –