2012-12-18 65 views
4

假如我這樣做(注:下面的語法可能是不正確的,但不要擔心......它只是在那裏做出點)做數據庫事務防止其他用戶干擾它

Start Transaction 
INSERT INTO table (id, data) VALUES (100,20), (100,30); 
SELECT * FROM table WHERE id = 100; 
End Transaction 

因此,選擇的目標是從剛剛插入前一個插入表的所有信息以及之前的INSERT中插入...

現在假設在執行期間,INSERT執行後,某些其他用戶也執行ID = 100的INSERT ...

事務的下一步中的SELECT語句是否也會獲得由其他用戶執行的INSERT插入的行,還是隻會得到事務內前一個INSERT插入的兩行?

順便說一句,我使用的是MySQL,所以請調整你的答案到MySQL

回答

6

這完全取決於數據庫連接使用的事務隔離。

根據MySQL 5.0 Certification Study Guide

enter image description here

頁420描述了隔離級別

  • 髒讀是讀通過的另一做出提交的修改一個事務處理3個交易條件。假設事務T1修改一行。如果事務T2讀取行並且看到修改,儘管T1還沒有提交,那就是髒讀。這是一個問題的原因之一是,如果T1回滾,更改被撤消,但T2不知道。
  • 當事務執行兩次相同的檢索,但每次都得到不同的結果時,將發生不可重複的讀取。假設T1讀取一些行,然後T2更改其中一些行並提交更改。如果T1在再次讀取行時看到更改,則會得到不同的結果;最初的閱讀是不可重複的。這是一個問題,因爲T1沒有從同一個查詢得到一致的結果。
  • 幻影是出現在以前不可見的地方的行。假設T1和T2開始,T1讀取一些行。如果T2插入新的並且T1再次讀取時看到該行,則該行是幻影。

頁421描述了四個(4)事務隔離級別:

  • READ-UNCOMMITTED:允許一個事務看到其他事務做出提交的更改。此隔離級別允許發生髒讀,不可重複讀取和幻像。
  • READ-COMMITTED:允許交易查看由其他交易所做的更改,僅當他們已經提交時。未提交的更改仍然不可見。這個隔離級別允許不可重複的讀取和幻像發生。
  • REPEATABLE READ(默認值):確保事務發出兩次相同的SELECT,無論其他事務提交或未提交的更改如何,它都會獲得相同的結果。換句話說,它從相同查詢的不同執行中獲得一致的結果。在某些數據庫系統中,REPEATABLE READ隔離級別允許幻影,如果另一個事務插入新行,則在SELECT語句之間的第二個SELECT中將看到它們。 InnoDB不是這樣; REPEATABLE READ級別不出現幻影。
  • SERIALIZABLE:完全隔離一個交易與其他交易的影響。它與REPEATABLE READ相似,但有一個限制:一個事務選擇的行不能被另一個事務更改,直到第一個事務完成。

隔離級別可以爲您的數據庫會話全局設置,您的會話中,或特定的交易:

SET GLOBAL TRANSACTION ISOLATION LEVEL isolation_level; 
SET SESSION TRANSACTION ISOLATION LEVEL isolation_level; 
SET TRANSACTION ISOLATION LEVEL isolation_level; 

其中ISOLATION_LEVEL是以下值之一:

  • 'READ UNCOMMITTED'
  • 'READ COMMITTED'
  • 'REPEATABLE READ'
  • 'SERIALIZABLE'

my.cnf您可以設置默認的還有:

[mysqld] 
transaction-isolation = READ-COMMITTED 
0

該交易將使它看起來像在交易中的語句,而不必與其他事務的任何干擾運行。大多數DBMS(包括MySQL)爲事務維護ACID屬性。在你的情況下,你對A for Atomic感興趣,這意味着DBMS將使你的交易中的所有語句看起來像原子一樣無中斷地運行。

2

當其他用戶正在更新同一行時,將應用行級別鎖定。所以他只能在交易結束後才能進行更改。所以你會看到你插入的結果集。希望這可以幫助。

0

只有需要訪問表中相同行的用戶才能生效。否則用戶不會受到影響。

但是,它稍微複雜一點,因爲行鎖定可以是讀鎖定或寫鎖定。

以下是InnoDB存儲引擎的說明。

2

干擾對於SQL數據庫事務來說是一個模糊的詞。交易可以看到的行數部分由其isolation level決定。

因此,選擇的目標是獲得來自 剛剛通過前面的插入和僅由前 INSERT插入表中的所有信息...

前段插入是也有點模糊。

可能應該在之前提交插入問題您嘗試讀取它。否則,在您控制的某些條件下而不是,該事務可能會回滾,並且ID = 100的行可能實際上不存在。

當然,承諾之後,其他交易可以自由更改「id」,「value」或兩者的值。 (如果他們有足夠的權限,那就是)。

0

出於效率原因,開發人員不會將事務設置爲完全相互隔離。 數據庫支持倍數isolation級別,即可串行化,可重複讀取,已提交讀取和未提交讀取。他們從最嚴格到最不嚴格的清單。

相關問題