mysql事務、mysql隔離級别、mysql鎖、mysql資料一緻性、Spring事務、Spring事務傳播性之間的關系 一直有些模糊,整理一下。
mysql事務:
在mysql中,隻有使用了Innodb引擎的資料庫或表才支援事務
事務處理可以用來維護資料庫的完整性,保證成批的sql語句要麼全部執行,要麼全部不執行
事務用來管理insert,update,delete語句
事務要滿足四個條件(ACID):原子性(Atomicity)、一緻性(Consistency)、隔離性(Isolation)、持久性(Durability)
原子性:一個事務(transaction)中的所有操作,要麼全部完成,要麼全部不完成。
事務在執行過程中發生錯誤,會被復原(Rollback)到事務開始前的狀态,就像這個事務從來沒有執行過一樣
一緻性:在事務開始前和事務結束後,資料庫的完整性沒有被破壞。
這表示寫入的資料必須完全符合所有的預設規則,這包含資料的精确度、串聯性以及後續資料庫可以自發性的完成預定的工作。
隔離性:資料庫允許多個并發事務同時對其資料進行讀寫和修改,隔離性可以防止多個事務并發執行時,由于交叉執行而導緻資料的不一緻。
事務隔離分為不同級别,InnoDB 存儲引擎提供事務的隔離級别有:讀未送出(Read uncommitted)、讀送出(read committed)、可重複讀(repeatable read)和串行化(Serializable)
持久性:事務處理結束後,對資料的修改就是永久的,即便系統故障也不會丢失。
在 MySQL 指令行的預設設定下,事務都是自動送出的,即執行 SQL 語句後就會馬上執行 COMMIT 操作。是以要顯式地開啟一個事務務須使用指令 BEGIN 或 START TRANSACTION,或者執行指令 SET AUTOCOMMIT=0,用來禁止使用目前會話的自動送出。
SQL标準定義了4類隔離級别,包括了一些具體規則,用來限定事務内外的哪些改變是可見的,哪些是不可見的。低級别的隔離級一般支援更高的并發處理,并擁有更低的系統開銷。
四種隔離級别和可能産生問題:
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5SOiRDZjNmN0cTZklTZjRWYyQTM4cjZ2kTO4ImZ0MDMz8CX0JXZ252bj91Ztl2Lc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
Read Uncommitted:所有事務都可以看到其他未送出事務的執行結果。
會導緻【髒讀Drity Read】:讀了錯誤的資料。Read Uncommitted隔離級别時,b事務可以讀取另外a事務未送出的資料,如果a事務rollback,則b事務讀取的資料是錯誤的。
Read Committed:一個事務隻能看見已經送出事務所做的改變。
會導緻【不可重複讀Non-repeatable read】:兩次讀的某條資料不一緻。Read Committed隔離級别時,在一個事務的兩次查詢之間,其他事務送出并更新了該條資料,導緻兩次查詢的資料不一緻。
Repeatable Read:同一個事務中多次讀取相同的資料傳回的結果是一樣的。MySQL的預設事務隔離級别,一個事務在執行過程中可以看到其他事務已經送出的新插入的記錄(讀已經送出的,其實是讀早于本事務開始且已經送出的),但是不能看到其他事務對已有記錄的更新(即晚于本事務開始的),并且,該事務不要求與其他事務是“可串行化”的。
在目前事務送出之前,其它不論什麼事務均不能夠改動或删除目前事務已讀取的資料。并發性低于READ COMMITTED。由于已讀資料的共享鎖在整個事務期間持有,而不是在每一個語句結束時釋放。
會導緻【幻讀Phantom Read】:當使用者讀取某範圍資料行時,另一事務在此範圍内插入新行,當使用者再次讀取此範圍資料行時,讀取到新的幻影行。
Serializable:最高的隔離級别,它通過強制事務排序,使之不可能互相沖突,進而解決幻讀問題。簡言之,它是在每個讀的資料行上加上共享鎖。在這個級别,可能導緻大量的逾時現象和鎖競争。
注意⚠️:不可重複讀重點在于update和delete,而幻讀的重點在于insert。
重點:InnoDB引擎中Repeatable Read的實作原理。
手動測試,mysql裡沒有出現幻讀的問題。
spring事務的七種隔離級别如下:
當存在一個事務時,則支援目前事務,如果沒有事務則:1、開啟新事務。2、非事務執行。3、抛出異常。
總是開啟一個新事務
總是非事務執行,如果目前事務存在:1、挂起該事務。2、抛出異常。
PROPAGATION_NESTED 如果活動事務存在,則運作在嵌套事務中,如果沒有活動事務,則安裝PROPAGATION_REQUIRED運作