天天看點

【MySQL】資料庫事務深入分析一、前言二、常見的并發問題三、事務隔離級别四、資料庫日志有哪些?五、資料庫事務控制六、事務的ACID特性

一、前言

隻有InnoDB引擎支援事務,下邊的内容均以InnoDB引擎為預設條件

二、常見的并發問題

1、髒讀

一個事務讀取了另一個事務未送出的資料

2、不可重複讀

一個事務對同一資料的讀取結果前後不一緻。兩次讀取中間被其他事務修改了

3、幻讀

幻讀是指事務讀取某個範圍的資料時,因為其他事務的操作導緻前後兩次讀取的結果不一緻。幻讀和不可重複讀的差別在于,不可重複讀是針對确定的某一行資料而言,而幻讀是針對不确定的多行資料。因而幻讀通常出現在帶有查詢條件的範圍查詢中

三、事務隔離級别

1、讀未送出(READ UNCOMMITTED)

可能産生髒讀、不可重複讀、幻讀

2、讀已送出(READ COMMITTED)

避免了髒讀,可能産生不可重複讀、幻讀

3、可重複讀(REPEATABLE READ)(mysql預設隔離級别)

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

4、串行化(SERIALIZABLE)

串行化可以避免所有可能出現的并發異常,但是會極大的降低系統的并發處理能力

四、資料庫日志有哪些?

1、undo日志

undo日志用于存放資料修改被修改前的值

UNDO LOG中分為兩種類型,一種是 INSERT_UNDO(INSERT操作),記錄插入的唯一鍵值;

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

2、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,可以提高事務送出的速度;

3、binlog日志

用于資料庫主從複制的記錄,是二進制格式。在事務送出之後進行一個磁盤寫入。

這裡注意下redo log 跟binary log 的差別,redo log 是存儲引擎層産生的,而binary log是資料庫層産生的。假設一個大事務,對tba做10萬行的記錄插入,在這個過程中,一直不斷的往redo log順序記錄,而binary log不會記錄,直到這個事務送出,才會一次寫入到binary log檔案中

五、資料庫事務控制

1、預設情況下,開啟事務自動送出功能。每執行一個sql,都會對應一個事務的送出

2、spring會将底層連接配接的自動送出特性設定為false。使用手動送出

六、事務的ACID特性

1、原子性(Atomicity)

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

2、一緻性(Consistency)

事務的執行結果必須使資料庫從一個一緻性狀态到另一個一緻性狀态。一緻性狀态是指:1.系統的狀态滿足資料的完整性限制(主碼,參照完整性,check限制等) 2.系統的狀态反應資料庫本應描述的現實世界的真實狀态,比如轉賬前後兩個賬戶的金額總和應該保持不變。

3、隔離性(Isolation)

并發執行的事務不會互相影響,其對資料庫的影響和它們串行執行時一樣。比如多個使用者同時往一個賬戶轉賬,最後賬戶的結果應該和他們按先後次序轉賬的結果一樣。

4、持久性(Durability)

事務一旦送出,其對資料庫的更新就是持久的。任何事務或系統故障都不會導緻資料丢失。

5、redo log和undo log實作了原子性、一緻性、持久性

6、鎖機制實作了隔離性

6.1、快照讀

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

6.2、目前讀

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

6.3、鎖定讀

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

  SELECT ... LOCK IN SHARE MODE

  給記錄假設共享鎖,這樣一來的話,其它事務隻能讀不能修改,直到目前事務送出

  SELECT ... FOR UPDATE

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

6.4、一緻性非鎖定讀

  consistent read (一緻性讀),InnoDB用多版本來提供查詢資料庫在某個時間點的快照。如果隔離級别是REPEATABLE READ,那麼在同一個事務中的所有一緻性讀都讀的是事務中第一個這樣的讀讀到的快照;如果是READ COMMITTED,那麼一個事務中的每一個一緻性讀都會讀到它自己重新整理的快照版本。Consistent read(一緻性讀)是READ COMMITTED和REPEATABLE READ隔離級别下普通SELECT語句預設的模式。一緻性讀不會給它所通路的表加任何形式的鎖,是以其它事務可以同時并發的修改它們。

轉載于:https://www.cnblogs.com/wangzhongqiu/p/11370606.html