目錄
事務特性acid屬性
併發事務帶來的問題
事務隔離級別
事務實現原理
閒聊【邁莫coding】
事務特性acid屬性
事務特性指的就是acid,如圖所示:
在這裡插入描述
原子性 atomicity :乙個事務(transaction)中的所有操作,或者全部完成,或者全部不完成,不會結束在中間某個環節。事務在執行過程中發生錯誤,會被恢復(rollback)到事務開始前的狀態,就像這個事務從來沒有執行過一樣。即,事務不可分割、不可約簡。
一致性 consistency :在事務開始和完成時,資料必須保持一致。這意味著所有相關的資料規則都必須應用於事務的修改,以保持資料的完整性;事務結束時,所有的內部資料結構(如b樹索引或雙向鍊錶)也都必須是正確的。
隔離性 isolation :資料庫允許多個併發事務同時對其資料進行讀寫和修改的能力,隔離性可以防止多個事務併發執行時由於交叉執行而導致資料的不一致。事務隔離分為不同級別,包括讀未提交(read uncommitted)、讀提交(read committed)、可重複讀(repeatable read)和序列化(serializable)。
永續性 durability :事務處理結束後,對資料的修改就是永久的,即便系統故障也不會丟失。
併發帶來的問題
更新丟失(lost updated)
當兩個或多個事務選擇同一行,然後基於最初選定的值更新該行時,由於每個事務都不知道其他事務的存在,就會發生丟失更新問題,也就是最後的更新會覆蓋掉先前的更新操作。
髒讀(dirty reads)
乙個事務正在對一條記錄進行修改時,在這個事務完成並提交之前,這條記錄的資料就會處於不一致的狀態;這時,另乙個事務來讀取同一條記錄,如果不加控制,第二個事務讀取了這些「髒」資料,並據此進行進一步操作,就會產生未提交的資料依賴關係。這種現象被稱為"髒讀"。
一句話:事務a讀取了事務b已經修改但未提交的資料,如果事務b進行回滾,事務a讀取的資料無效,不符合一致性。
不可重複讀(non-repeatable reads)
乙個事務在讀取某些資料後的某個時間,再次讀取以前讀過的資料,卻發現其讀取的資料發生了改變,或者這些資料被刪除,這種現象被稱為"不可重複讀"。
一句話:事務a讀取事務b提交的修改資料,不符合隔離型。
幻讀(phantom reads)
乙個事務按照相同的查詢條件重新讀取以前檢索的記錄,卻發現其他的事務插入滿足查詢條件的記錄,這種現象被稱為"幻讀"。
一句話:事務a讀取事務b提交的新增資料,不符合隔離型。
事務隔離級別
上述所說的"髒讀","不可重複讀","幻讀"這些問題,其實就是資料庫讀一致性問題,必須由資料庫提供的事務隔離機制來進行解決。
在這裡插入描述
mysql預設事務隔離級別為可重複讀(rr)
資料庫的事務隔離越嚴格,併發***越小,但付出的代價越大;因為事務隔離本質就是使事務在一定程度上處於序列狀態,這本身就是和併發相矛盾的。
同時,不同的應用對讀一致性和事務隔離級別是不一樣的,比如許多應用對資料的一致性沒那麼個高要求,相反,對併發有一定要求。
事務實現原理
事務的實現是基於資料庫的儲存引擎。 不同的儲存引擎對事務的支援不一樣,接下來以mysql資料庫中innodb引擎來解說.
innodb引擎是mysql的預設儲存引擎,隔離級別為不可重複讀(rr),並在在rr隔離級別下通過mvcc解決不可重複讀問題,通過間隙鎖解決幻讀問題。因此,innodb的rr隔離級別實現了序列化級別的效果,而且還保留了很好的併發效能。
事務隔離性是通過鎖來實現的,而事務的原子性,一致性和永續性都是事務日誌來實現的。 也就redo log日誌和undo log日誌,如果想看詳細的日誌介紹,請看我先前的文章<> 校招mysql那些事兒|日誌模組binlog/redolog/undolog,這裡只粗略的介紹redo log和undo log如何實現事務的原子性,一致性和永續性
redo log
redo log被稱為重寫日誌;事務日誌通過redo log和innodb引擎的日誌緩衝(innodb log buffer)實現在事務開啟的時候,事務的操作,都會寫入redo log日誌中,進而寫入到innodb儲存引擎的日誌緩衝中,在事務提交前,這些緩衝日誌都會提前重新整理到磁碟上進行持久化,這也是mysql老提的wal技術。
在buffer pool中對映的資料檔案才會慢慢重新整理到磁碟。此時如果資料庫崩潰或者宕機,那麼當系統重啟進行恢復時,就可以根據redo log中記錄的日誌,把資料庫恢復到崩潰前的乙個狀態。未完成的事務,可以繼續提交,也可以選擇回滾,這基於恢復的策略而定。
undo log
undo log主要為事務的回滾服務。在事務執行的過程中,除了記錄redo log,還會記錄一定量的undo log。
undo log記錄了資料在每個操作前的狀態,如果事務執行過程中需要回滾,就可以根據undo log進行回滾操作。
單個事務的回滾,只會回滾當前事務做的操作,並不會影響到其他的事務做的操作。
以下是undo+redo事務的簡化過程
假設有2個數值,分別為a和b,值為1,2
start transaction;
記錄 a=1 到undo log;
update a = 3;
記錄 a=3 到redo log;
記錄 b=2 到undo log;
update b = 4;
記錄b = 4 到redo log;
將redo log重新整理到磁碟
commit
在1-8的任意一步系統宕機,事務未提交,該事務就不會對磁碟上的資料做任何影響。如果在8-9之間宕機,恢復之後可以選擇回滾,也可以選擇繼續完成事務提交,因為此時redo log已經持久化。若在9之後系統宕機,記憶體對映中變更的資料還來不及刷回磁碟,那麼系統恢復之後,可以根據redo log把資料刷回磁碟。
所以,redo log其實保障的是事務的永續性和一致性,而undo log則保障了事務的原子性。
閒聊讀完文章,自己是不是和mysql事務的cp率又提高了
mysql事務機制 Mysql事務機制
mysql事務是指將資料庫從一種一致性狀態轉到另一種一致性狀態 mysql事務具有acid特性 原子性 atomicity 事務中的所有操作,要麼全部執行,要麼都不執行 一致性 consistency 事務開始和結束後,資料庫的完整性不會被破壞 隔離性 isolation 事務之間互不影響。事務的隔...
mysql安全機制 Mysql安全機制
在mysql下mysql庫中有6個許可權表 mysql.user 使用者字段,許可權字段,安全字段,資源控制字段 mysql.db mysql.host 使用者字段,許可權字段 mysql.tables priv,mysql.columms priv,mysql.procs priv 一 使用者管理...
mysql排序機制 MySQL 排序機制
在 mysql 中經常使用 order by 對資料進行排序,其實排序這個行為是比較消耗 io 的過程,有時候需要回表多次才可以完成排序,所以在任何時候都需要對排序的原理要心知肚明。在 mysql 中排序按照是否使用外部儲存可以分為,記憶體排序和外部排序兩種。根據排序所需的字段可以分成 rowid ...