天天看點

spring mysql 事務_spring事務和mysql的隔離級别

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類隔離級别,包括了一些具體規則,用來限定事務内外的哪些改變是可見的,哪些是不可見的。低級别的隔離級一般支援更高的并發處理,并擁有更低的系統開銷。

四種隔離級别和可能産生問題:

spring mysql 事務_spring事務和mysql的隔離級别

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運作