1. 程式人生 > 實用技巧 >資料庫事務的特性以及MySQL資料庫的隔離級別

資料庫事務的特性以及MySQL資料庫的隔離級別

前言

瞭解資料庫事務的特性,能夠讓我們更好的理解程式設計的時候對資料庫事務的控制。本篇文章主要講解了資料庫事務的特性以及MySQL資料庫在不同的事務隔離級別下遇到的不同情況。

資料庫事務的概念

資料庫事務是訪問並可能更新資料庫中各個資料項的一個程式執行單元,通常包含對資料庫進行讀或者寫的一個操作序列
一個典型的資料庫事務如下:

begin transaction //事務開始
SQL1
SQL2
commit/rollback//事務結束或者回滾

資料庫事務的特性

資料庫事務的特性有四個,簡稱ACID,即原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)、永續性(Durability)。下面我們來說明一下這四個特性。

原子性(Atomicity)

原子性是指,同一個事務中的多個數據庫的操作是一起完成的,要麼所有的資料庫操作都操作成功,如果有一個數據庫的操作失敗,則其他的操作也都會回滾。也就是說,要麼全部成功,要麼全部回滾。

一致性(Consistency)

一致性是指,一個事務或者多個事務在開始前的資料的狀態和結束後的資料的狀態要保持一致。這裡的一致性有點抽象,我們舉個例子來說明:假設在資料庫中庫存表中的某商品的庫存總量為10,購買量為0,剩餘量為10。現在有兩個使用者購買了1件該商品,那麼在這兩個使用者購買完成後,該商品的購買量應該為2,剩餘量應該為8,它們的總和等於庫存量10,而不應該為其他的數值。

隔離性(Isolation)

隔離性是指,不同事務之間,他們是互相獨立的,不會相互的干擾。就是說,一個事務裡對某一資料進行操作,不會影響其他事務對同樣資料的操作。他們操作完成以後對資料庫的影響和他們序列執行時的結果一樣

永續性(Durability)

永續性是指,一個事務一旦提交成功,它對資料庫的修改是持久的。任何事務或者系統故障都不會導致資料的丟失。

事務併發會產生的異常

事務的四大特性,可以很好的規範程式設計師根據不同的業務場景以及資料庫不同的隔離級別,對資料庫的事務進行合理的操作,從而來避免一些多個事務併發執行時所產生的異常情況。事務併發執行時,產生以下幾種異常情況。


這四種異常會因為資料庫的隔離級別不同而產生,接下來我們先來講一下MySQL資料的四種隔離級別。

MySQL資料庫的四個隔離級別

MySQL資料庫的四個隔離級別從低到高依次為:1.讀未提交(read uncommitted);2.讀已提交(read committed);3.可重複讀(repeatable read)--MySQL預設的隔離級別;4.序列化(serializable)

以上四種隔離級別,分別會產生的異常情況如下圖所示:

讀未提交(read uncommitted)

如果有兩個事務,都在操作同一條資料的一個整型欄位paramA的值(假設兩個事務沒操作之前值為0),其中一個事務A正在讀取變數paramA的值的時候,而另一個事務B更改了變數paramA的值(更改為1),但是還沒有提交paramA的值,那麼此時事務A讀取到的paramA的值為1。這裡發生了髒讀,如果事務B提交失敗的話,那麼事務A拿到的變數paramA的值與資料庫本來的值是不一致的。此級別同樣會產生幻讀不可重複讀的現象(同一事務不同時間讀取的記錄條數不一致)。

讀已提交(read committed)

如果有兩個事務,都在操作同一條資料的一個整型欄位paramA的值(假設兩個事務沒操作之前值為0),其中一個事務A正在讀取paramA的值的時候,而另一個事務B更改了paramA的值(更改為1),但是還沒有提交paramA的值,那麼此時事務A讀取到的paramA的值為0;如果事務A在讀取變數paramA的值時,事務B已經更改了paramA的值為1,並且提交了事務,那麼事務A讀取到的值就為1。這個隔離級別會導致同一事務在多次讀取一條記錄的某個值時可能會讀取不同的結果,也即不可重複讀的情況;當然,也會產生幻讀的現象。

可重複讀(repeatable read)

還是上述場景,如果事務A在第一次讀取paramA的時候,事務B沒有更改paramA的值,那麼事務A讀取到的paramA的值為0,在事務A第二次讀取paramA的時候,事務B更改了paramA的值並提交了事務,則事務A第二次讀取到的paramA的值仍為0。此隔離級別為MySQL資料庫的預設隔離界別,但這種隔離級別也會產生幻讀

序列化(serializable)

仍以上述兩個事務為例,此時如果事務A讀取某一表的一條資料中欄位paramA的值(此時為0),此時如果事務B如果想修改該表中該記錄欄位paramA的值時,則修改不了,處於等待狀態;但是事務B如果是讀取欄位paramA的值則允許讀取。如果事務A在更改該表該記錄的欄位paramA的值,則事務B不能做任何操作(讀取、增加、修改、刪除)的操作,只有等事務A結束後才允許進行操作。這種隔離級別容易產生超時和鎖競爭情況。

髒讀(Dirty Read)

幻讀(Phantom Read)

不可重複讀(Unrepeatable Read)

丟失更新(Lost Update)