MySQL之senior(十)——事務
定義
-
一個事務其實就是一個完整的業務邏輯。是一個最小的工作單元。不可再分。 什麼是一個完整的業務邏輯? 假設轉賬,從A賬戶向B賬戶中轉賬10000. 將B賬戶的錢加上10000(update語句) 這就是一個完整的業務邏輯。
以上的操作是一個最小的工作單元,要麼同時成功,要麼同時失敗,不可再分。 這兩個update語句要求必須同時成功或者同時失敗,這樣才能保證錢是正確的。
-
只有DML語句(insert delete update) 才會有事務這一說,其它語句和事務無關! 因為 只有以上的三個語句是資料庫表中資料進行增、刪、改的。
-
假設所有的業務,只要一條DML語句就能完成,還有必要存在事務機制嗎? 正是因為做某件事的時候,需要多條DML語句共同聯合起來才能完成, 所以需要事務的存在。如果任何一件複雜的事兒都能一條DML語句搞定, 那麼事務則沒有存在的價值了。
到底什麼是事務呢? 說到底,說到本質上,一個事務其實就是多條DML語句同時成功,或者同時失敗! 事務:就是批量的DML語句同時成功,或者同時失敗!
-
事務是怎麼做到多條DML語句同時成功和同時失敗的呢? InnoDB儲存引擎:提供一組用來記錄事務性活動的日誌檔案
在事務的執行過程中,每一條DML的操作都會記錄到“事務性活動的日誌檔案”中。
提交事務: 清空事務性活動的日誌檔案,將資料全部徹底持久化到資料庫表中。 提交事務標誌著,事務的結束。並且是一種全部成功的結束。
回滾事務: 將之前所有的DML操作全部撤銷,並且清空事務性活動的日誌檔案 回滾事務標誌著,事務的結束。並且是一種全部失敗的結束。
-
怎麼提交事務,怎麼回滾事務? 提交事務:commit; 語句 回滾事務:rollback; 語句(回滾永遠都是隻能回滾到上一次的提交點!commit點)
事務對應的英語單詞是:transaction
在mysql當中預設的事務行為是怎樣的? mysql預設情況下是支援自動提交事務的。(自動提交)
這種自動提交實際上是不符合我們的開發習慣,因為一個業務通常是需要多條DML語句共同執行才能完成的,為了保證資料的安全,必須要求同時成功之後再提交,所以不能執行一條就提交一條。
怎麼將mysql的自動提交機制關閉掉呢? 先執行這個命令:start transaction;
-
事務包括4個特性?
A:原子性 atomic 說明事務是最小的工作單元。不可再分。 C:一致性 concordant 所有事務要求,在同一個事務當中,所有操作必須同時成功,或者同時失敗, 以保證資料的一致性。 I:隔離性 isolated A事務和B事務之間具有一定的隔離。 教室A和教室B之間有一道牆,這道牆就是隔離性。 A事務在操作一張表的時候,另一個事務B也操作這張表會那樣??? D:永續性 durable 事務最終結束的一個保障。事務提交,就相當記憶體上的資料 儲存到硬碟上!
-
重點研究事務的隔離性!!(檢視隔離級別:SELECT @@transaction_isolation )
A教室和B教室中間有一道牆,這道牆可以很厚,也可以很薄。這就是事務的隔離級別。 這道牆越厚,表示隔離級別就越高。 事務和事務之間的隔離級別:4個級別 讀未提交:read uncommitted(最低的隔離級別)《沒有提交就讀到了》 什麼是讀未提交? 事務A可以讀取到事務B未提交的資料。 這種隔離級別存在的問題就是: 髒讀現象!(Dirty Read) 我們稱讀到了髒資料。 這種隔離級別一般都是理論上的,大多數的資料庫隔離級別都是二檔起步! 讀已提交:read committed《提交之後才能讀到》 什麼是讀已提交? 事務A只能讀取到事務B提交之後的資料。 這種隔離級別解決了什麼問題? 解決了髒讀的現象。 這種隔離級別存在什麼問題? 不可重複讀取資料。 什麼是不可重複讀取資料呢? 在事務開啟之後,第一次讀到的資料是3條,當前事務還沒有 結束,可能第二次再讀取的時候,讀到的資料是4條,3不等於4 稱為不可重複讀取。 這種隔離級別是比較真實的資料,每一次讀到的資料是絕對的真實。 oracle資料庫預設的隔離級別是:read committed 可重複讀:repeatable read《提交之後也讀不到,永遠讀取的都是剛開啟事務時的資料》 什麼是可重複讀取? 事務A開啟之後,不管是多久,每一次在事務A中讀取到的資料 都是一致的。即使事務B將資料已經修改,並且提交了,事務A 讀取到的資料還是沒有發生改變,這就是可重複讀。 可重複讀解決了什麼問題? 解決了不可重複讀取資料。 可重複讀存在的問題是什麼? 可以會出現幻影讀。 每一次讀取到的資料都是幻象。不夠真實! 早晨9點開始開啟了事務,只要事務不結束,到晚上9點,讀到的資料還是那樣! 讀到的是假象。不夠絕對的真實。 mysql中預設的事務隔離級別就是這個!!!!!!!!!!! 序列化/序列化:serializable(最高的隔離級別) 這是最高隔離級別,效率最低。解決了所有的問題。 這種隔離級別表示事務排隊,不能併發! synchronized,執行緒同步(事務同步) 每一次讀取到的資料都是最真實的,並且效率是最低的。
-
驗證各種隔離級別
被測試的表t_user 驗證:read uncommited mysql> set global transaction isolation level read uncommitted; 事務A 事務B -------------------------------------------------------------------------------- use bjpowernode; use bjpowernode; start transaction; select * from t_user; start transaction; insert into t_user values('zhangsan'); select * from t_user; 驗證:read commited mysql> set global transaction isolation level read committed; 事務A 事務B -------------------------------------------------------------------------------- use bjpowernode; use bjpowernode; start transaction; start transaction; select * from t_user; insert into t_user values('zhangsan'); select * from t_user; commit; select * from t_user; 驗證:repeatable read mysql> set global transaction isolation level repeatable read; 事務A 事務B -------------------------------------------------------------------------------- use bjpowernode; use bjpowernode; start transaction; start transaction; select * from t_user; insert into t_user values('lisi'); insert into t_user values('wangwu'); commit; select * from t_user; 驗證:serializable mysql> set global transaction isolation level serializable; 事務A 事務B -------------------------------------------------------------------------------- use bjpowernode; use bjpowernode; start transaction; start transaction; select * from t_user; insert into t_user values('abc'); select * from t_user;