站長資訊網
        最全最豐富的資訊網站

        總結數據庫事務與 MySQL 事務

        mysql教程總結數據庫事務與 MySQL 事務

        總結數據庫事務與 MySQL 事務

        推薦(免費):mysql教程

        事務特點:ACID

        從業務角度出發,對數據庫的一組操作要求保持4個特征:

        • Atomicity(原子性):一個事務必須被視為一個不可分割的最小工作單元,整個事務中的所有操作要么全部提交成功,要么全部失敗回滾,對于一個事務來說,不可能只執行其中的一部分操作。
        • Consistency(一致性):數據庫總是從一個一致性狀態轉換到另一個一致狀態。下面的銀行列子會說到。
        • Isolation(隔離性):通常來說,一個事務所做的修改在最終提交以前,對其他事務是不可見的。注意這里的“通常來說”,后面的事務隔離級級別會說到。
        • Durability(持久性):一旦事務提交,則其所做的修改就會永久保存到數據庫中。此時即使系統崩潰,修改的數據也不會丟失。(持久性的安全性與刷新日志級別也存在一定關系,不同的級別對應不同的數據安全級別。)

        為了更好地理解ACID,以銀行賬戶轉賬為例:

        START TRANSACTION;SELECT balance FROM checking WHERE customer_id = 10233276;UPDATE checking SET balance = balance - 200.00 WHERE customer_id = 10233276;UPDATE savings SET balance = balance + 200.00 WHERE customer_id = 10233276;COMMIT;
        • 原子性:要么完全提交(10233276的checking余額減少200,savings 的余額增加200),要么完全回滾(兩個表的余額都不發生變化)
        • 一致性:這個例子的一致性體現在 200元不會因為數據庫系統運行到第3行之后,第4行之前時崩潰而不翼而飛,因為事務還沒有提交。
        • 隔離性:允許在一個事務中的操作語句會與其他事務的語句隔離開,比如事務A運行到第3行之后,第4行之前,此時事務B去查詢checking余額時,它仍然能夠看到在事務A中被減去的200元(賬戶錢不變),因為事務A和B是彼此隔離的。在事務A提交之前,事務B觀察不到數據的改變。
        • 持久性:這個很好理解。
        • 事務的隔離性是通過鎖、MVCC等實現 (MySQL鎖總結)
        • 事務的原子性、一致性和持久性則是通過事務日志實現(見下)

        事務的隔離級別

        并發事務帶來的問題

        • 更新丟失(Lost Update):當兩個或多個事務選擇同一行,然后基于最初選定的值更新該行時,由于每個事務都不知道其他事務的存在,就會發生丟失更新問題 --最后的更新覆蓋了由其他事務所做的更新。例如,兩個編輯人員制作了同一 文檔的電子副本。每個編輯人員獨立地更改其副本,然后保存更改后的副本,這樣就覆蓋了原始文檔。 最后保存其更改副本的編輯人員覆蓋另一個編輯人員所做的更改。如果在一個編輯人員完成并提交事務之前,另一個編輯人員不能訪問同 一文件,則可避免此問題。
        • 臟讀(Dirty Reads):一個事務正在對一條記錄做修改,在這個事務完成并提交前, 這條記錄的數據就處于不一致狀態; 這時, 另一個事務也來讀取同一條記錄,如果不加控制,第二個事務讀取了這些“臟”數據,并據此做進一步的處理,就會產生未提交的數據依賴關系。這種現象被形象地叫做”臟讀”。
        • 不可重復讀(Non-Repeatable Reads):一個事務在讀取某些數據后的某個時間,再次讀取以前讀過的數據,卻發現其讀出的數據已經發生了改變、或某些記錄已經被刪除了!這種現象就叫做“不可重復讀” 。
        • 幻讀 (Phantom Reads): 一個事務按相同的查詢條件重新讀取以前檢索過的數據,卻發現其他事務插入了滿足其查詢條件的新數據,這種現象就稱為“幻讀” 。

        幻讀和不可重復讀的區別:

        • 不可重復讀的重點是修改:在同一事務中,同樣的條件,第一次讀的數據和第二次讀的數據不一樣。(因為中間有其他事務提交了修改)
        • 幻讀的重點在于新增或者刪除:在同一事務中,同樣的條件,,第一次和第二次讀出來的記錄數不一樣。(因為中間有其他事務提交了插入/刪除)

        并發事務處理帶來的問題的解決辦法:

        • “更新丟失”通常是應該完全避免的。但防止更新丟失,并不能單靠數據庫事務控制器來解決,需要應用程序對要更新的數據加必要的鎖來解決,因此,防止更新丟失應該是應用的責任。

        • “臟讀” 、 “不可重復讀”和“幻讀” ,其實都是數據庫讀一致性問題,必須由數據庫提供一定的事務隔離機制來解決:

        • 一種是加鎖:在讀取數據前,對其加鎖,阻止其他事務對數據進行修改。

        • 另一種是數據多版本并發控制(MultiVersion Concurrency Control,簡稱 MVCC 或 MCC),也稱為多版本數據庫:不用加任何鎖, 通過一定機制生成一個數據請求時間點的一致性數據快照 (Snapshot), 并用這個快照來提供一定級別 (語句級或事務級) 的一致性讀取。從用戶的角度來看,好象是數據庫可以提供同一數據的多個版本。

        SQL標準定義了4類隔離級別,每一種級別都規定了一個事務中所做的修改,哪些在事務內和事務間是可見的,哪些是不可見的。低級別的隔離級一般支持更高的并發處理,并擁有更低的系統開銷。

        第1級別:Read Uncommitted(讀取未提交內容)

        • 所有事務都可以看到其他未提交事務的執行結果
        • 本隔離級別很少用于實際應用,因為它的性能也不比其他級別好多少
        • 該級別引發的問題是——臟讀(Dirty Read):讀取到了未提交的數據

        第2級別:Read Committed(讀取提交內容)

        • 這是大多數數據庫系統的默認隔離級別(但不是MySQL默認的)

        • 它滿足了隔離的簡單定義:一個事務只能看見已經提交事務所做的改變

        • 這種隔離級別出現的問題是——不可重復讀(Nonrepeatable Read):不可重復讀意味著我們在同一個事務中執行完全相同的select語句時可能看到不一樣的結果。導致這種情況的原因可能有:

        • 有一個交叉的事務有新的commit,導致了數據的改變;

        • 一個數據庫被多個實例操作時,同一事務的其他實例在該實例處理其間可能會有新的commit

        第3級別:Repeatable Read(可重讀)

        • 這是MySQL的默認事務隔離級別
        • 它確保同一事務的多個實例在并發讀取數據時,會看到同樣的數據行
        • 此級別可能出現的問題——幻讀(Phantom Read):當用戶讀取某一范圍的數據行時,另一個事務又在該范圍內插入了新行,當用戶再讀取該范圍的數據行時,會發現有新的“幻影” 行
        • InnoDB和Falcon存儲引擎通過多版本并發控制(MVCC,Multiversion Concurrency Control)機制解決幻讀問題;InnoDB還通過間隙鎖解決幻讀問題

        多版本并發控制 :

        Mysql的大多數事務型存儲引擎實現都不是簡單的行級鎖。基于提升并發性考慮,一般都同時實現了多版本并發控制(MVCC),包括Oracle、PostgreSQL。不過實現各不相同。

        MVCC的實現是通過保存數據在某一個時間點快照來實現的。也就是說不管實現時間多長,每個事物看到的數據都是一致的。

        分為樂觀(optimistic)并發控制和悲觀(pressimistic)并發控制。

        MVCC是如何工作的:

        InnoDB的MVCC是通過在每行記錄后面保存兩個隱藏的列來實現。這兩個列一個保存了行的創建時間,一個保存行的過期時間(刪除時間)。當然存儲的并不是真實的時間而是系統版本號(system version number)。每開始一個新的事務,系統版本號都會自動新增。事務開始時刻的系統版本號會作為事務的版本號,用來查詢到每行記錄的版本號進行比較。

        REPEATABLE READ(可重讀)隔離級別下MVCC如何工作:

        • SELECT

        InnoDB會根據以下條件檢查每一行記錄:

        1. InnoDB只查找版本早于當前事務版本的數據行,這樣可以確保事務讀取的行要么是在開始事務之前已經存在要么是事務自身插入或者修改過的
        2. 行的刪除版本號要么未定義,要么大于當前事務版本號,這樣可以確保事務讀取到的行在事務開始之前未被刪除

        只有符合上述兩個條件的才會被查詢出來

        • INSERT

        InnoDB為新插入的每一行保存當前系統版本號作為行版本號

        • DELETE

        InnoDB為刪除的每一行保存當前系統版本號作為行刪除標識

        • UPDATE

        InnoDB為插入的一行新紀錄保存當前系統版本號作為行版本號,同時保存當前系統版本號到原來的行作為刪除標識

        保存這兩個版本號,使大多數操作都不用加鎖。使數據操作簡單,性能很好,并且能保證只會讀取到復合要求的行。不足之處是每行記錄都需要額外的存儲空間,需要做

        贊(0)
        分享到: 更多 (0)
        網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
        主站蜘蛛池模板: 国产91在线精品| 亚洲第一精品福利| 国产精品午夜一级毛片密呀| 精品a在线观看| 亚洲av永久无码精品漫画| 久久精品99久久香蕉国产色戒| 亚洲午夜久久久精品影院| 91精品视频在线| 91精品最新国内在线播放| 午夜精品久久久久9999高清| 国产精品第12页| 国产精品看高国产精品不卡| 精品无码国产一区二区三区51安| 国产91久久精品一区二区| 精品日韩亚洲AV无码一区二区三区| 99久久婷婷国产综合精品草原| 精品国产一区二区三区在线观看| 亚洲中文字幕无码久久精品1 | 久久se精品一区精品二区国产 | 国产精品乱码高清在线观看| 国产欧美精品区一区二区三区| 无码少妇精品一区二区免费动态| 久久精品国产一区二区三区| 久久精品国产99国产电影网| 国产精品VIDEOSSEX久久发布| 日韩精品人妻系列无码专区| 欧美人与动牲交a欧美精品| 国产高清精品一区| 亚洲国产精品无码久久| 国产精品午夜国产小视频| jizzjizz国产精品久久| 99久久人妻无码精品系列| 国内精品久久久久久久久| 国产人成精品午夜在线观看| 国产在线精品免费aaa片| 久久国产精品偷99| 99爱在线视频这里只有精品| 国产成人精品优优av| 亚洲av日韩av天堂影片精品| 国产欧美精品一区二区色综合| 久久夜色精品国产亚洲|