2008-12-12 62 views
11

簡短背景:我們剛剛開始使用Hibernate將ERP系統遷移/重新實現爲Java,目標是使用該系統的併發用戶數爲50-100個用戶。我們使用MS SQL Server作爲數據庫服務器,這對於這種負載來說已經足夠了。如果有的話,ERP的最佳默認事務隔離級別是什麼?

現在,舊系統根本不使用任何交易,並依靠關鍵部分(例如庫存更改)設置手動鎖定(使用標誌)並釋放它們。這就像手動事務管理。但是有時候數據不一致問題。在新系統中,我們希望使用交易來消除這些問題。

現在的問題:這將是一個很好的/合理默認事務隔離,給出約85%的OLTP和15%OLAP的使用水平,使用一個ERP系統?或者我應該總是根據每個任務決定使用哪個交易級別?

另外要提醒的四個事務隔離級別:讀取未提交,提交讀,可重複讀取,SERIALIZABLE

回答

14

99遍100,read committed是正確答案。這可以確保您只能看到其他會話承諾的更改(因此,假設您已正確設計交易,結果是一致的)。但它並沒有強加可重複讀取或序列化強加的鎖定開銷(特別是在非Oracle數據庫中)。

偶爾,您可能想要運行一個報告,您願意犧牲速度的準確性並設置讀未提交隔離級別。這並不是一個好主意,但它偶爾是一個合理可接受的解決方法來鎖定爭用問題。

當你有一個進程需要在整個運行過程中看到一組一致的數據時,偶爾會使用可串行化和可重複讀取,而不管其他事務正在進行什麼。將月末對賬流程設置爲可序列化可能是適當的,例如,如果有大量程序代碼,用戶將在流程運行時進行更改的可能性以及流程需要的可能性確保它始終能夠看到調整開始時的數據。

1

對於SQL Server(也可能是最重要的RDBMS),我會堅持使用默認。對於SQL Server,這是READ COMMITTED。更重要的是,你開始壓榨數據庫,更少,而且你遇到了一致性問題。

+0

SQL Server的默認值可能是READ COMMITTED,但我相信ADO.net的默認值是SERIALIZABLE,在這種情況下,如果他使用.net,則更重要。 – 2008-12-12 22:08:14

+1

@Robert這是不正確的。默認值是SQL Server的默認值。例如,當您更改SqlTransaction上的隔離級別時,它會在服務器上執行SET TRANSACTION ISOLATION LEVEL XXXX。 – chadmyers 2008-12-14 01:11:50

1

不要忘記SNAPSHOT,它正好在SERIALIZABLE下面。

這取決於數據在報告中的準確性有多重要。它確實是一項逐個任務的事情。

2

真的很大程度上取決於你如何設計你的應用程序,簡單的答案就是在READ_COMMITTED下運行。

您可以提出一個論點,如果您在設計系統時考慮到可以使用READ_UNCOMMITTED作爲默認值,並且只在需要時增加隔離級別。無論如何,絕大多數交易都會成功,因此讀取未提交的數據不會有什麼大不了的。

方式隔離級別會影響您的查詢取決於您的目標數據庫。例如,Sybase和MSSQL等數據庫在運行READ_COMMITTED時必須鎖定比Oracle等數據庫更多的資源。

0

閱讀未提交絕對是大多數論壇中的失敗者。但是,有理由使用它,這超出了經常指出的「速度與準確性」的問題。

比方說,你有:

  • 事務T1:寫B,讀取,(有的更多的工作),提交。
  • 事務T2:寫入A,讀取B,(更多工作),提交。

隨着讀提交,上述事務將不會發布,直到提交。然後,您可以運行T1正在等待T2釋放A,並且T2正在等待T1釋放B.這裏兩個事務在鎖中發生衝突。

您可以重新編寫這些程序來避免這種情況(例如:總是按字母順序獲取資源!)。儘管如此,如果有太多的併發用戶和數萬行代碼,這個問題很可能變得非常可能並且非常難以診斷和解決。

另一種方法是使用Read Uncommitted。然後,假設可能存在髒讀,則設計交易。我個人發現這個問題比互鎖的火車殘骸更具局部性和可治療性。

髒的問題,可以讀取通過

  • (1)回滾被搶佔:沒有。這應該是硬件故障,網絡故障或程序崩潰情況下的最後一道防線。

  • (2)使用應用程序鎖定到創建在更高層次的抽象,其中每個鎖更接近 真實世界的資源或行動工作 鎖定機制。