2012-07-04 78 views
1

我們將Hibernate 3.6.0.Final與JPA 2和Spring 3.0.5一起用於在tomcat 7和MySQL 5.5上運行的大型企業應用程序。大多數應用程序中的事務處理時間不到一秒鐘,並且更新了5-10個實體,但在某些使用情況下,我們需要在單個事務中更新10-20K個實體,這需要幾分鐘的時間,因此超過70%的時間此類事務因StaleObjectStateException失敗,因爲其中一些實體被其他事務更新。如何在事務更新數千個實體時避免StaleObjectStateException?

我們通常在所有表中維護版本列,如果出現StaleObjectStateException,我們通常會重試,但由於這些longs事務總是很長,所以如果我們繼續重試,那麼我也不太確定我們能夠逃脫StaleObjectStateException。

也有很多活動不斷在忙碌的時間更新這些實體,所以我們不能採用悲觀的方法,因爲它可能會暫停系統中的許多活動。

請建議如何解決這樣長的交易問題,因爲我們無法產生數千個獨立和小型交易,因爲我們不能在一些失敗的&某些成功的交易中負擔混亂的數據。

+1

在繁忙時間之外執行這些用例嗎? –

+0

我希望這是可能的,但實際上這些應用程序在工作時間內被大量使用,應該觸發它的人也僅在這些時間內工作。如果我們要求他們在深夜工作,那麼對於工程團隊來說,這將是一件恥辱,因爲我們無法處理這種負載。 – ThinkFloyd

回答

1

在一次事務中修改20,000個實體真的很多,比平時多得多。

我不能給你一個通用的解決方案,但這裏有一些想法如何解決這個問題。

1)使用LockMode.UPGRADE(見pessimistic locking)。在那裏你顯式地生成了「SELECT FOR UPDATE」,這會阻止其他用戶在鎖定時修改這些行。 這應該避免你的問題,但是如果你有太多的大型事務,它可能會產生死鎖(取決於你的編程)或超時。

2)更改數據模型以避免這些大型事務。爲什麼你需要更新10,000行?也許有可能把這些信息在很多行中更新到一個新表中,並讓它只被引用,所以你只需要更新新表中的幾行。

3)使用StatelessSession而不是Session。在這種情況下,您不會在異常之後回滾,而是可以更正問題並繼續(在您的情況下重新加載同時修改的實體,並對重新加載的實體上的大型事務進行修改)。這也許可以讓您以行爲基礎來處理關鍵事件(同時修改行),而不是整個大型事務。

相關問題