事務是用來保證一組資料庫的操作,要麼全部成功,要麼全部失敗;應用場景較多:如銀行轉賬,訂票等。
mysql的事務是在引擎層支援的,原生的myisam不支援,因此主流使用innodb引擎。
原子性顧名思義,不可分割,要麼所有指令都成功,要麼所有指令都失敗;
一致性事務開始前和事務結束後,資料庫的狀態都是正常的狀態,即資料不會錯亂。
舉個例子:在乙個事務中,對a進行減1操作,對b進行加1操作,然後事務完成,從外部邏輯來看,這個事務成功後,a = a-1,b=b+1,如果一致性沒有保障的話,可能a-1的操作成功了,而b+1的操作沒成功,這樣的結果是a=a-1,b=b,導致邏輯結果不一致。
永續性事務一旦提交成功,則意味著結果已經成功入庫,即使資料庫崩潰也不影響。
隔離性事務之間的可見性,分為多重隔離級別,msyql的事務隔離級別有讀未提交,讀提交,可重複讀,可序列化,隔離級別越高,效能就越低。
讀未提交
乙個事務過程中,對資料庫的操作,在其他事務中會讀到,無論該事務是否提交。如事務1中,修改了a的資料,還沒有提交;此時,事務b,查詢a的資料,已經是事務1中修改過的結果。該級別會導致髒讀,幻讀,不可重複讀。
讀提交乙個事務只有在成功提交後,結果才能被其他事務看到。如事務1中,修改了a的資料,還沒有提交;此時,事務b,查詢a的資料,是a未被修改的結果;當事務1提交後,此時,事務b,查詢a的資料,是a被修改的結果。該級別會導致幻讀,不可重複讀。
可重複讀
乙個事務在執行過程中,其他事務修改了改事務操作相關的資料並提交成功,該事務也不會不感知相關的修改。該級別會導致幻讀(會讀到別的事務插入的資料)。
如事務1中,修改了a的資料,還沒有提交;此時,事務b,查詢a的資料,是a未被修改的結果;當事務1提交後,此時,事務b,查詢a的資料,還是是a未被修改的結果。
可序列化
事務之間只能序列執行。如何保障序列?通過加鎖的方式實現。關於資料庫中的鎖,以後再深入描述。
幾個名詞
髒讀:如事務讀取某條記錄時,插入該記錄的事務隨後做了回滾,這就導致髒讀(資料不是真實資料)。
幻讀:如事務在插入時檢查過不存在的條目,再做插入,但是插入時,卻發現該條目已經存在。這就是在插入前,被其他事務插入了該條目導致(資料是真實資料,但是前後讀取的結果不一致)。
不可重複讀:同樣的查詢條件,再次讀取的資料卻不同了。
僅介紹可重複讀的大體實現方式。
每條記錄在更新的時候,都會同時記錄一條回滾日誌,記錄的值可以通過回滾操作,得到前乙個或多個狀態的值。
對於可重複度級別的事務,事務啟動時,會建立乙個檢視,該檢視獲取的資料是當前時間點的資料,獲取方式,就是通過回滾記錄來獲取。
那麼,各個記錄的回滾日誌何時刪除呢?當沒有事務需要相關的回滾日誌時,就會被刪除。基於此,需要注意不要使用長事務,長事務會導致回滾日誌無法及時清理,而占用大量儲存;同時,長事務還占用鎖資源,對這個庫都會產生影響,因此,在開發過程中,需要注意這點。
MySQL基礎學習筆記 事務
使用場景說明 事物能夠保證資料的完整性和一致性,讓使用者的操作更加安全。在使用事物之前,先要確保表的儲存引擎是innodb型別,只有這個型別才可以使用事物,mysql資料庫中表的儲存引擎預設是innodb型別。開始事物 提交事物 回滾事物 begin 或 start transaction 說明 取...
mysql 筆記 事務
一 問題讀取 1.髒讀 dirty read 事務1更新了某一條記錄,但未提交 事務2讀取到新的未提交記錄 事務1回滾。2.不可重複讀取 nonrepeatable read 不可重複讀,是指在資料庫訪問中,乙個 事務範圍內兩個相同的查詢卻返回了不同資料。例子 事務1讀取某一條記錄 事務2修改事務1...
mysql筆記 事務
寫日誌為什麼比直接寫磁碟要快?使用事務日誌,儲存引擎在修改表的資料時,只需要修改其記憶體拷貝,再把該修改行為記錄到硬碟上的事務日誌中,而不用每次都將修改的資料本身持久到磁碟。事務日誌採用的是追加的方式,因此寫日誌的操作是磁碟上一小塊區域內的順序i o,而不是隨機i o,所以快很多。事務日誌持久以後,...