資料庫事務與隔離等級

來源:互聯網
上載者:User

標籤:資料庫操作   資料庫管理   持久性   隔離   先來   

事務(transaction)是資料庫管理系統的執行單位,可以是一個資料庫操作(如Select操作)或者是一組操作序列。事務ACID屬性,即原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)、持久性(Durability)。

原子性:保證事務中的所有操作全部執行或全部不執行。例如執行轉賬事務,要麼轉賬成功,要麼失敗。成功,則金額從轉出帳戶轉入到目的帳戶,並且兩個帳戶金額將發生相應的變化;失敗,則兩個賬戶的金額都不變。不會出現轉出帳戶扣了錢,而目的帳戶沒有收到錢的情況。

一致性:保證資料庫始終保持資料的一致性——事務操作之前是一致的,事務操作之後也是一致的,不管事務成功與否。如上面的例子,轉賬之前和之後資料庫都保持資料上的一致性。

隔離性:多個事務並發執行的話,結果應該與多個事務串列執行效果是一樣的。顯然最簡單的隔離就是將所有事務都串列執行:先來先執行,一個事務執行完了才允許執行下一個。但這樣資料庫的效率低下,如:兩個不同的事務只是讀取同一批資料,這樣完全可以並發進行。為了控制並發執行的效果就有了不同的隔離等級。下面將詳細介紹。

持久性:持久性表示事物操作完成之後,對資料庫的影響是持久的,即使資料庫因故障而受到破壞,資料庫也應該能夠恢複。通常的實現方式是採用日誌。

 

    髒讀(dirty read):當一個事務讀取另一個事務尚未提交的修改時,產生髒讀。

    非重複讀(non-repeatable read):同一查詢在同一事務中多次進行,由於其他提交事務所做的修改或刪除,每次返回不同的結果集,此時發生非重複讀。

    幻像讀(phantom read):同一查詢在同一事務中多次進行,由於其他提交事務所做的插入操作,每次返回不同的結果集,此時發生幻像讀。


交易隔離等級(transaction isolation levels):隔離等級就是對對事務並發控制的等級。ANSI/ ISO SQL將其分為序列化(SERIALIZABLE)、可重複讀(REPEATABLE READ)、讀已提交(READ COMMITED)、讀未提交(READ UNCOMMITED)四個等級。為了實現隔離等級通常資料庫採用鎖(Lock)。一般在編程的時候只需要設定隔離等級,至於具體採用什麼鎖則由資料庫來設定。首先介紹四種等級,然後舉例解釋後面三個等級(可重複讀、讀已提交、讀未提交)中會出現的並發問題。

序列化(SERIALIZABLE):所有事務都一個接一個地串列執行,這樣可以避免幻讀(phantom reads)。對於基於鎖來實現並發控制的資料庫來說,序列化要求在執行範圍查詢(如選取年齡在10到30之間的使用者)的時候,需要擷取範圍鎖(range lock)。如果不是基於鎖實現並發控制的資料庫,則檢查到有違反串列操作的事務時,需要滾回該事務。

可重複讀(REPEATABLE READ):所有被Select擷取的資料都不能被修改,這樣就可以避免一個事務前後讀取資料不一致的情況。但是卻沒有辦法控制幻讀,因為這個時候其他事務不能更改所選的資料,但是可以增加資料,因為前一個事務沒有範圍鎖。

讀已提交(READ COMMITED):被讀取的資料可以被其他事務修改。這樣就可能導致不可重複讀取。也就是說,事務的讀取資料的時候擷取讀鎖,但是讀完之後立即釋放(不需要等到事務結束),而寫鎖則是事務提交之後才釋放。釋放讀鎖之後,就可能被其他事物修改資料。該等級也是SQL Server預設的隔離等級。

讀未提交(READ UNCOMMITED):這是最低的隔離等級,允許其他事務看到沒有提交的資料。這種等級會導致髒讀(Dirty Read)。

 例子:下面考察後面三種隔離等級對應的並發問題。假設有兩個事務。事務1執行查詢1,然後事務2執行查詢2,然後提交,接下來事務1中的查詢1再執行一次。查詢基於以下表進行:

users

id  name   age

                                  1   Joe    20

                                  2   Jill   25


可重複讀(幻讀,phantom reads)

一個事務中先後各執行一次同一個查詢,但是返回的結果集卻不一樣。發生這種情況是因為在執行Select操作的時候沒有擷取範圍鎖(Range Lock),導致其他事務仍然可以插入新的資料。

Transaction 1                                                 Transaction 1

/* Query 1 */

SELECT * FROM users

WHERE age BETWEEN 10 AND 30;

   

                                 

                                /* Query 2 */

                                INSERT INTO users VALUES ( 3, ‘Bob‘, 27 );                                COMMIT;/* Query 1 */SELECT * FROM usersWHERE age BETWEEN10 AND 30;注意transaction 1對同一個查詢語句(Query 1)執行了兩次。 如果採用更進階別的隔離等級(即序列化)的話,那麼前後兩次查詢應該返回同樣的結果集。但是在可重複讀隔離等級中卻前後兩次結果集不一樣。但是為什麼叫做可重複讀等級呢?那是因為該等級解決了下面的不可重複讀取問題。讀已提交(不可重複讀取,Non-repeatable reads)在採用鎖來實現並發控制的資料庫系統中,不可重複讀取是因為在執行Select操作的時候沒有加讀鎖(read lock)。Transaction 1                                           Transaction2 /* Query 1 */SELECT * FROM users WHERE id = 1;                                                 /* Query 2 */                                                UPDATE users SET age = 21 WHERE id = 1;                                                COMMIT;/* Query 1 */SELECT * FROM users WHERE id = 1;

在這個例子當中,Transaction 2提交成功,所以Transaction 1第二次將擷取一個不同的age 值.在SERIALIZABLE和REPEATABLE READ隔離等級中,資料庫應該返回同一個值。而在READ COMMITTED和READ UNCOMMITTED層級中資料庫返回更新的值。這樣就出現了不可重複讀取。

讀未提交 (髒讀,dirty reads)

如果一個事務2讀取了另一個事務1修改的值,但是最後事務1滾回了,那麼事務2就讀取了一個髒資料,這也就是所謂的髒讀。發生這種情況就是允許事務讀取未提交的更新。

Transaction 1                                       Transaction2

 

/* Query 1 */

SELECT * FROM users WHERE id = 1;

 

                                                /* Query 2 */

                                                UPDATE users SET age = 21 WHERE id = 1;

/* Query 1 */

SELECT * FROM users WHERE id = 1;

 

 

 

                                                RollBack


綜上述,可以等到下面的表格:

650) this.width=650;" src="/e/u261/themes/default/images/spacer.gif" style="background:url("/e/u261/lang/zh-cn/images/localimage.png") no-repeat center;border:1px solid #ddd;" alt="spacer.gif" />

650) this.width=650;" src="http://s3.51cto.com/wyfs02/M00/43/5D/wKiom1PZ8lDAQ3G5AAC_OF-fmls927.jpg" title="aaaa.jpg" alt="wKiom1PZ8lDAQ3G5AAC_OF-fmls927.jpg" />

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.