2011-09-17 227 views
3

我有幾個關於題目題目的問題。首先,讓我們假設我們使用JDBC,並且我們有2個事務T1和T2。在T1中,我們在一個特定的行上執行select語句。然後我們對該行執行更新。在事務T2中,我們在同一行執行select語句。交易,鎖,隔離級別

這裏有幾個問題:

1)什麼時候交易T1收購上提到的行上的鎖?我假設它在選擇語句執行期間發生?

2)事務T1持有多長時間鎖?在事務提交/回滾之前是否持有它,還是在此之前釋放鎖?

3)隔離級別是否控制使用哪種類型的鎖?例如:

a)如果我們使用讀提交事務T2的隔離級別,這是否意味着T2將使用SELECT語句的共享讀鎖定,以便在T1更新行之後T2將不會訪問到那一行(避免髒讀),並且在T1沒有更新行的情況下,T2將具有對該行的讀訪問權限?

B)如果我們使用讀事務T2提交隔離級別,這是否意味着T2將採用無鎖的SELECT語句,所以它可以讀取數據,即使它是由T1修改(允許髒讀)。

所以,我最擔心的問題是誰在控制決定應用什麼類型的鎖?它是交易的隔離級別,還是有其他方法?如果對問題3的回答是肯定的(隔離級別控制着什麼鎖使用),那麼如果我們在mysql數據庫上使用jdbc例如,我們使用select來更新或選擇共享模式結構中的鎖,會發生什麼?正如我記得第一個是排他鎖,而第二個是共享讀鎖。它將如何反映我們的事務隔離級別?

5)如果重複讀取隔離級別的情況下獲取什麼樣的鎖?讓我們假設我們的T2(具有可重複讀取隔離級別)在同一行上有兩個select語句,而T1與之前一樣。首先在T2中執行一條select語句,然後執行並提交T1,然後執行T2 second select。這種情況甚至可能嗎?如果事務持有它們的鎖直到它們被提交/回滾,我認爲T1將不能獲得獨佔鎖更新,直到T2完成?

EDIT:還有一個問題:

6)在多版本併發控制系統中,當我們設置序列化隔離級別,事務A即試圖更新一些行由另一個事務B更新(B更新A開始後的行)將被回滾。我想問的是,在樂觀鎖定情況下發生的事情不是那麼相似嗎?

在此先感謝。

+1

這是很多問題......答案取決於所使用的具體數據庫/版本......所以我們在談論什麼數據庫? – Yahia

+0

好吧,讓我們說它是MySQL 5.5 :) – Kovasandra

+0

好吧 - 這不是enogh,因爲MySQL可以用於不同的存儲引擎,而這些存儲引擎又對交易表現出很大的不同,所以:什麼是存儲引擎? – Yahia

回答

1

你的問題是一個很好的問題。瞭解獲取何種類型的鎖可以深入理解DBMS。在SQL Server中,在所有隔離級別(讀取未提交,讀取提交(默認),可重複讀取,可序列化)下,執行寫入操作的獨佔鎖定。

無論隔離級別如何,事務結束時都會釋放專用鎖。

隔離級別之間的差異是指共享(讀)鎖獲取/釋放的方式。

在讀取未提交隔離級別下,不會收集共享鎖。在此隔離級別下,可能會發生稱爲「髒讀」的併發問題。

在讀取提交隔離級別下,爲相關記錄獲取共享鎖。當前指令結束時,共享鎖將被釋放。此隔離級別可防止「髒讀」,但由於記錄可由其他併發事務更新,因此可發生「不可重複讀」或「幻影讀」。

在可重複讀取隔離級別下,獲取交易持續時間的共享鎖。可以防止「髒讀」和「不可重複讀」,但仍然可以發生「幻像讀」。

在可序列化的隔離級別下,範圍內的共享鎖是在事務持續時間內獲取的。沒有發生上述併發問題,但性能大幅降低,存在發生死鎖的風險。