【MySQL】數據庫事務深刻分析

1、前言

只有InnoDB引擎支持事務,下邊的內容均以InnoDB引擎爲默認條件html

2、常見的併發問題

一、髒讀

一個事務讀取了另外一個事務未提交的數據mysql

二、不可重複讀

一個事務對同一數據的讀取結果先後不一致。兩次讀取中間被其餘事務修改了spring

三、幻讀

幻讀是指事務讀取某個範圍的數據時,由於其餘事務的操做致使先後兩次讀取的結果不一致。幻讀和不可重複讀的區別在於,不可重複讀是針對肯定的某一行數據而言,而幻讀是針對不肯定的多行數據。於是幻讀一般出如今帶有查詢條件的範圍查詢中sql

3、事務隔離級別

一、讀未提交(READ UNCOMMITTED)

可能產生髒讀、不可重複讀、幻讀數據庫

二、讀已提交(READ COMMITTED)

避免了髒讀,可能產生不可重複讀、幻讀併發

三、可重複讀(REPEATABLE READ)(mysql默認隔離級別)

避免了髒讀,不可重複讀。經過區間鎖技術避免了幻讀日誌

四、串行化(SERIALIZABLE)

串行化能夠避免全部可能出現的併發異常,可是會極大的下降系統的併發處理能力htm

4、數據庫日誌有哪些?

一、undo日誌

undo日誌用於存放數據修改被修改前的值索引

UNDO LOG中分爲兩種類型,一種是 INSERT_UNDO(INSERT操做),記錄插入的惟一鍵值;事務

一種是 UPDATE_UNDO(包含UPDATE及DELETE操做),記錄修改的惟一鍵值以及old column記錄。

二、redo日誌

mysql會將一個事務中的全部sq先l記錄到redo log中,而後再將記錄從redo log同步到數據文件中

它能夠帶來這些好處:

  • 當buffer pool中的dirty page 尚未刷新到磁盤的時候,發生crash,啓動服務後,可經過redo log 找到須要從新刷新到磁盤文件的記錄;
  • buffer pool中的數據直接flush到disk file,是一個隨機IO,效率較差,而把buffer pool中的數據記錄到redo log,是一個順序IO,能夠提升事務提交的速度;

三、binlog日誌

用於數據庫主從複製的記錄,是二進制格式。在事務提交以後進行一個磁盤寫入。

這裏注意下redo log 跟binary log 的區別,redo log 是存儲引擎層產生的,而binary log是數據庫層產生的。假設一個大事務,對tba作10萬行的記錄插入,在這個過程當中,一直不斷的往redo log順序記錄,而binary log不會記錄,直到這個事務提交,纔會一次寫入到binary log文件中

5、數據庫事務控制

一、默認狀況下,開啓事務自動提交功能。每執行一個sql,都會對應一個事務的提交

二、spring會將底層鏈接的自動提交特性設置爲false。使用手動提交

6、事務的ACID特性

一、原子性(Atomicity)

事務中的全部操做做爲一個總體像原子同樣不可分割,要麼所有成功,要麼所有失敗。

二、一致性(Consistency)

事務的執行結果必須使數據庫從一個一致性狀態到另外一個一致性狀態。一致性狀態是指:1.系統的狀態知足數據的完整性約束(主碼,參照完整性,check約束等) 2.系統的狀態反應數據庫本應描述的現實世界的真實狀態,好比轉帳先後兩個帳戶的金額總和應該保持不變。

三、隔離性(Isolation)

併發執行的事務不會相互影響,其對數據庫的影響和它們串行執行時同樣。好比多個用戶同時往一個帳戶轉帳,最後帳戶的結果應該和他們按前後次序轉帳的結果同樣。

四、持久性(Durability)

事務一旦提交,其對數據庫的更新就是持久的。任何事務或系統故障都不會致使數據丟失。

五、redo log和undo log實現了原子性、一致性、持久性

六、鎖機制實現了隔離性

6.一、快照讀

讀取的是快照版本,也就是歷史版本。普通的SELECT就是快照讀

6.二、當前讀

讀取的是最新版本。UPDATE、DELETE、INSERT、SELECT ...  LOCK IN SHARE MODE、SELECT ... FOR UPDATE是當前讀。

6.三、鎖定讀

  在一個事務中,標準的SELECT語句是不會加鎖,可是有兩種狀況例外。SELECT ... LOCK IN SHARE MODE 和 SELECT ... FOR UPDATE。

  SELECT ... LOCK IN SHARE MODE

  給記錄假設共享鎖,這樣一來的話,其它事務只能讀不能修改,直到當前事務提交

  SELECT ... FOR UPDATE

  給索引記錄加鎖,這種狀況下跟UPDATE的加鎖狀況是同樣的

6.四、一致性非鎖定讀

  consistent read (一致性讀),InnoDB用多版原本提供查詢數據庫在某個時間點的快照。若是隔離級別是REPEATABLE READ,那麼在同一個事務中的全部一致性讀都讀的是事務中第一個這樣的讀讀到的快照;若是是READ COMMITTED,那麼一個事務中的每個一致性讀都會讀到它本身刷新的快照版本。Consistent read(一致性讀)是READ COMMITTED和REPEATABLE READ隔離級別下普通SELECT語句默認的模式。一致性讀不會給它所訪問的表加任何形式的鎖,所以其它事務能夠同時併發的修改它們。

相關文章
相關標籤/搜索