<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Chan Chen Coding...

    數據庫事務與隔離等級詳解

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

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

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

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

    持久性:持久性表示事物操作完成之后,對數據庫的影響是持久的,即使數據庫因故障而受到破壞,數據庫也應該能夠恢復。通常的實現方式是采用日志。

     

    事務隔離級別(transaction isolation levels):隔離級別就是對對事務并發控制的等級。ANSIISOSQL將其分為串行化(SERIALIZABLE)、可重復讀(REPEATABLE READ)、讀已提交(READ COMMITED)、讀未提交(READ UNCOMMITED)四個等級。為了實現隔離級別通常數據庫采用鎖(Lock)。一般在編程的時候只需要設置隔離等級,至于具體采用什么鎖則由數據庫來設置。首先介紹四種等級,然后舉例解釋后面三個等級(可重復讀、讀已提交、讀未提交)中會出現的并發問題。

    串行化(SERIALIZABLE):所有事務都一個接一個地串行執行,這樣可以避免幻讀(phantom reads)。對于基于鎖來實現并發控制的數據庫來說,串行化要求在執行范圍查詢(如選取年齡在1030之間的用戶)的時候,需要獲取范圍鎖(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 2

    /* 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 users
    WHERE age BETWEEN 10 AND 30;

     

    注意transaction 1對同一個查詢語句(Query 1)執行了兩次。 如果采用更高級別的隔離等級(即串行化)的話,那么前后兩次查詢應該返回同樣的結果集。但是在可重復讀隔離等級中卻前后兩次結果集不一樣。但是為什么叫做可重復讀等級呢?那是因為該等級解決了下面的不可重復讀問題。

    讀已提交(不可重復讀,Non-repeatable reads)

    在采用鎖來實現并發控制的數據庫系統中,不可重復讀是因為在執行Select操作的時候沒有加讀鎖(read lock)。

    Transaction 1

    Transaction 2

    /* 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

    Transaction 2

    /* 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

     

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

    隔離等級

    臟讀

    不可重復讀

    幻讀

    讀未提交

    YES

    YES

    YES

    讀已提交

    NO

    YES

    YES

    可重復讀

    NO

    NO

    YES

    串行化

    NO

    NO

    NO

     



    -----------------------------------------------------
    Silence, the way to avoid many problems;
    Smile, the way to solve many problems;

    posted on 2012-12-21 13:06 Chan Chen 閱讀(459) 評論(0)  編輯  收藏 所屬分類: DB

    主站蜘蛛池模板: 人妻无码久久一区二区三区免费| 亚洲爆乳大丰满无码专区| 中文日本免费高清| 爱情岛论坛网亚洲品质自拍| 色欲aⅴ亚洲情无码AV| 日本媚薬痉挛在线观看免费| 久久久亚洲精华液精华液精华液| 国产极品粉嫩泬免费观看| 噜噜噜亚洲色成人网站| 亚洲精品国产福利一二区| 中文字幕久无码免费久久 | 亚洲人成国产精品无码| www成人免费观看网站| 国产亚洲精品成人AA片新蒲金 | 好久久免费视频高清| 亚洲一区二区三区四区在线观看| 久久99青青精品免费观看| 亚洲婷婷综合色高清在线| 国产无人区码卡二卡三卡免费| 亚洲日韩精品国产一区二区三区 | 一二三四视频在线观看中文版免费 | 1000部夫妻午夜免费| 国产 亚洲 中文在线 字幕 | 久久精品国产69国产精品亚洲| 久久永久免费人妻精品| 亚洲第一成人在线| 免费国产高清视频| 日本免费一区二区三区| 亚洲精品免费网站| 精品国产亚洲男女在线线电影 | 免费无码不卡视频在线观看| 免费人人潮人人爽一区二区| 亚洲av中文无码乱人伦在线播放| 日韩欧毛片免费视频| 污污视频网站免费观看| 夜夜亚洲天天久久| 内射无码专区久久亚洲| 120秒男女动态视频免费| 免费一级做a爰片久久毛片潮| 亚洲午夜久久久精品影院| 麻豆国产精品入口免费观看|