一、什麼是事務
事務是資料庫操作的最小工作單位,乙個事務可以是一條sql語句,也可以是一組sql語句。
事務有四大特徵:原子性,永續性,隔離性,一致性,就是我們常說的acid
二、原子性
原子性的意思是說乙個事務裡的操作會組成乙個最小的執行單位,不可再分割,在乙個事務中,要麼操作都成功,要麼都失敗。比較經典的例子就是我們的轉賬,a向b轉賬,a要完成減錢,b要完成加錢,這些是都需要完成才能算乙個事務完成。如果在其中發生了錯誤那麼就需要回滾。回滾的時候就需要用到我們回滾日誌,undo log。因為我們目前常用的儲存引擎都是innodb,在innodb中還使用undo log + mvcc來實現事務的可重複讀和讀已提交這兩個隔離級別。
undo log分為兩種,一種是insert undo log,用來記錄插入操作產生的回滾日誌,一種是update undo log,用來記錄更新,刪除操作的時候產生的回滾日誌。
當我們要運算元據之前,就先把資料備份到undo log中,然後我們再對資料進行修改,在這個過程中如果出現了錯誤,那麼mysql就會利用undo log中的資料來恢復。
undo log的工作方式可以簡單的理解成記錄相反的操作到日誌中,比如我們更新的時候,他就記錄一條之前更新的狀態,我們刪除資料的時候他就會新增一條資料,我們新增資料的時候他就會刪除一條資料。
三、永續性
永續性的意思是說當我們事務提交之後,他形成的資料應該被永久化為資料庫中。也就是應該持久化到磁碟上,因為在記憶體中一斷電就沒了。
永續性實現的原理是redo log,前滾日誌。
因為我們在更新完一條記錄的時候,我們資料是先在記憶體中的,再從記憶體持久化到我們的磁碟。
因為資料一開始在記憶體中,如果斷電肯定資料就沒了,所以redo log就是為了解決這個問題。
當我們每次執行完dml操作之後,也就是當我們事務commit的時候,這裡其實有乙個非同步的操作。首先執行過程會寫入buffer pool,mysql會優先寫日誌,先保證日誌寫成功,寫日誌會有三種情況,0.寫到log buffer,1.直接寫到磁碟裡,然後每秒為單位寫到磁碟裡 2.寫到os buffer,然後每秒為單位寫到磁碟。這裡有乙個引數innodb_flush_log_at_trx_commit來控制,預設是直接寫到磁碟裡。而對於日誌的提交頻率都是每秒為單位,而我們真實的資料庫的資料,可能五秒再持久化一次到磁碟。
對於0和2這兩種方式,雖然都是寫到記憶體,但是還有有所差別的,因為log buffer屬於資料庫服務,而os buffer屬於作業系統,所以如果mysql服務掛了,那麼不會影響os buffer把資料寫到磁碟。
四、隔離性
隔離性是說事務之間的執行不應該產生相互影響,他們對資料庫的影響應該和他們序列執行的結果一樣。
但是如果是完成遵守隔離性,對併發的效能影響會比較大,所以一般來說我們工作中會對隔離性有所放寬。正是因為沒辦法兩全,所以產生了一些資料的問題,也就是髒讀,不可重讀,幻讀。sql的標準定義了四個隔離級別,分別是讀未提交,讀已提交,可重複讀,序列化。mysql預設隔離級別是可重複度。四個隔離級別分別是來解決這三種資料問題的。序列化是隔離級別是最高的隔離界別,這種隔離級別情況下,每個讀的資料行上都會加鎖,所以效率很慢,會導致大量的超時現象。可重複讀會出現幻讀,讀已提交會出現不可重讀和幻讀,讀未提交會出現髒讀,不可重讀,幻讀。
實現mysql的隔離級別主要利用的是鎖機制,利用鎖來解決了髒讀幻讀,不可重讀。mysql主要有三種級別的鎖,分別是行鎖,表鎖,頁鎖。表鎖不會出現死鎖,行鎖和頁鎖都有可能出現死鎖。
因為我們大部分是使用innodb的引擎,所以我也說一下innodb的鎖,就是兩種,共享鎖和排它鎖,他們都是行級別的鎖。共享是說同一行的資料,可以被多個事務獲取共享鎖,但是只可以讀,不能修改。排他鎖是指一行資料只能被乙個事務獲得排他鎖,獲取排他鎖的事務可以修改資料。
innodb還支援行鎖和表鎖並存。他這裡的實現原理是利用意向鎖,意向鎖也是兩種,意向共享鎖和意向排他鎖。意向共享鎖就是說在事務準備給資料行加共享鎖前,先給這個表加乙個意向共享鎖,意向排他鎖也是相同的意思。各個意向鎖之間是相容的,他設計這個的目的是:當事務想去進行鎖表時,可以先判斷意向鎖是否存在,存在時則可快速返回該錶不能啟用表鎖,否則就需要等待。
我們使用innodb主要是因為他支援行鎖,支援事務,innodb的行鎖是給索引加鎖實現的,只有通過索引檢索資料,才能使用行鎖,不然就是會使用表鎖。這裡又要提到乙個臨鍵鎖(next-key),其實臨鍵鎖就相當與記錄鎖(record locks)加上間隙鎖(gap locks)。記錄鎖很簡單是單條記錄的鎖,是單個的,間隙鎖也是見名知義,表示我們資料之間的空隙。就是我們的索引項有時候是不連續的,比如id有1,3,7,9這些id中間就有空隙,間隙鎖就是當我們進行範圍查詢的時候,會把這些空隙也鎖住。
通過上面的排他鎖,解決了髒讀,共享鎖解決了不可重複讀,臨鍵鎖解決了幻讀。
1.髒讀,幻讀,不可重讀
髒讀的意思是說多個事務在執行過程中,a事務讀取到了b事務還沒commit的資料,然後b事務又rollback回滾了,那麼a讀到的資料就是髒資料。
不可重讀是指在同乙個事務a中,我們對同一組資料進行兩次一模一樣的查詢,但是因為在這兩次查詢中間,有事務b修改了資料,導致事務a兩次查詢結果不一樣,這就出現了不可重複讀。
幻讀一般是我們在進行範圍查詢的時候,事務a對id大於10的資料進行查詢,同樣也是兩次查詢,在這個過程中,事務b新增或者刪除了資料,導致事a在查詢的時候兩次結果不一致。也就是是幻讀。
五、一致性
事務的一致性可以說是最重要的。即事務執行前後資料應該是一致的。還是那個轉賬的例子,當a向b轉錢,那麼最終結果a減錢b加錢,這兩個的和應該還是一樣的。事務的一致性實現的原理其實就是之前是三個特性,原子性,隔離性,永續性共同保證了一致性。
MySQL事務特性
目錄 什麼是事務?acid 原子性 atomicity 一致性 consistency 隔離性 isolation 永續性 durability 事務併發問題 事務隔離級別 一組原子性的sql指令集合,要麼全部執行成功,要麼全部執行失敗。整個事務所有操作要麼全部提交成功,要麼全部失敗回滾,不可能只成...
MySQL事務的特性
事務具有很嚴格的定義,必須同時滿足4個特徵 原子性 一致性 隔離性 永續性,也就是人們常說的acid標準 原子性,是指乙個事務必須被視為,乙個不可分割的最小工作單元,只有事務中所有的資料庫操作都執行成功,才算整個事務執行成功 事務中,如果有任何乙個sql語句執行失敗,已經執行成功的sql語句,也必須...
MySQL 事務和特性
事務是資料庫操作的最小工作單位,乙個事務可以是一條sql語句,也可以是一組sql語句。事務有四大特徵 原子性,永續性,隔離性,一致性,就是我們常說的acid 原子性的意思是說乙個事務裡的操作會組成乙個最小的執行單位,不可再分割,在乙個事務中,要麼操作都成功,要麼都失敗。比較經典的例子就是我們的轉賬,...