2013-02-13 173 views
1

我已經通過整個Microsoft站點了解SQL Server 2008 R2中的隔離級別。然而,在採納之前,我想向SO的專家提出建議。SQL Server 2008 R2中的隔離級別

我有一個基於PHP的網頁主要用作儀表板。用戶(不超過5個)每天將上傳大量數據(大約40,000行),大約70個用戶只准備訪問數據庫。請注意,我已經爲這5個用戶上傳了固定的時間表,但是我想對相同的數據丟失進行證明。請幫助我解決以下問題:

  • 什麼是我可以使用的最佳隔離級別?
  • 默認的READ COMMITTED隔離會幫助我嗎?
  • 還有一種方法可以通過SSMS爲TSQL語句以外的特定數據庫設置隔離級別嗎? (爲一個數據庫通用隔離)

70用戶將有下載選項,是有一個機會,如果所有或大部分試圖在同一時間下載該數據庫將遭到損壞?我如何避免相同?

專家的任何建議....

問候, 俞拉吉小號

+4

隔離級別爲**不是關於**屏蔽你的數據損壞,而是關於**鎖定數據**在變化和**閱讀數據**使用選擇*(承諾,uncommited,髒,幻影)*。對於大多數意圖和目的,默認隔離級別就足夠了。 – 2013-02-13 06:23:11

+1

btw:如果所有嘗試同時下載,則不必擔心數據庫遭到破壞。這就是[ACID](http://en.wikipedia.org/wiki/ACID#Consistency)中的一致性*(和耐久性)*的保證。 – 2013-02-13 06:31:50

回答

6

隔離級別是真正關心共享多久的數據是讀鎖被保留。但正如列文已經提到的那樣:那些關於防止數據庫中的「腐敗」的是NOT--這些是關於防止讀者和作者進入對方的方式。

第一項:任何寫操作(INSERTUPDATE)將總是需要在該行的獨家鎖和排它鎖不與任何其他兼容 - 所以,如果要更新的給定行已鎖定,任何UPDATE操作將不得不等待 - 沒有辦法解決這個問題。

對於讀取數據,SQL Server會出共享鎖 - 和隔離級別是如何長的持有。

默認隔離級別(READ COMMITTED)表示:SQL Server將嘗試獲取行上的共享鎖,如果成功,讀取行的內容,並再次釋放鎖的時候了。所以鎖只存在於被讀取行的短暫時間內。共享鎖與其他共享鎖兼容,所以任何數量的讀者可以同時讀取相同的行。然而,共享鎖會阻止排它鎖,所以共享鎖主要阻止相同行上的UPDATE

然後還有READ UNCOMMITTED隔離級別 - 基本上不會鎖定;這意味着它還可以讀取當前正在更新並且被獨佔鎖定的行 - 這樣您可能會得到未提交的數據 - 最終可能不會真正在數據庫中結束的數據(如果事務將其更新回滾) - 小心這個!

下一級是REPEATABLE READ,在這種情況下,一旦獲取共享鎖,將保留到當前事務終止。這會鎖定更多行並延長一段時間 - 讀取是可重複的,因爲您已經讀取的行被「鎖定在後面」的更新鎖定。

最終級別爲SERIALIZABLE,其中行的整個範圍(由SELECT中的WHERE子句定義)被鎖定,直到當前事務終止。

更新:比下載的部分(二次對我來說)我擔心的是5個用戶試圖在同一時間更新一個數據庫

更多。

好了,不要擔心 - SQL Server將肯定處理這個沒有任何麻煩!

如果這5個(甚至50個)併發用戶正在更新不同的行 - 他們甚至不會注意到其他人在附近。更新將會發生,在這個過程中沒有數據會受到傷害 - 一切都很好。

如果其中一些用戶試圖更新相同行 - 它們將被序列化。第一個將能夠獲得該行的排他鎖,進行更新,釋放鎖,然後繼續。現在,第二個用戶將獲得它的機會 - 獲得排他鎖,更新數據,釋放鎖,繼續。

當然:如果你不對它做任何事,第二個用戶的數據將會簡單地覆蓋第一個更新。這就是爲什麼需要進行併發檢查的原因。您應該檢查數據是否在讀取時間和寫入時間之間發生了變化;如果它發生了變化,這意味着其他人已經在同一時間更新過它 - >您需要爲這種情況考慮併發衝突解決策略(但這本身就是一個其他問題......)

+0

好帖子。您忘記了READ UNCOMMITTED隔離級別,足以滿足OP的需要;) – danihp 2013-02-13 06:41:26

+0

謝謝大家對此主題的建議和知識。不止是下載部分(對我來說是次要的),我擔心有5個用戶試圖同時更新一個數據庫。 – 2013-02-13 06:42:44

+2

@ user1926468:對於SQL Server,有五個併發用戶是**沒有** - 它很容易**確保沒有數據可以被兩個事務一次更新它們破壞。 – 2013-02-13 06:43:48