mysql事務詳解

  • 2019 年 10 月 3 日
  • 筆記

MySQL 事務主要用於處理操作量大,複雜度高的數據。比如開單,需要添加給訂單表增加記錄,還需要增加訂單的各種相關明細,操作複雜度高,這些操作語句需要構成一個事務。在 MySQL 命令行的默認設置下,事務都是自動提交的,即執行 SQL 語句後就會馬上執行 COMMIT 操作。因此要顯式地開啟一個事務務須使用命令 BEGIN 或 START TRANSACTION,或者執行命令 SET AUTOCOMMIT=0,用來禁止使用當前會話的自動提交。

事務

  • 在 MySQL 中只有使用了 Innodb 資料庫引擎的資料庫或表才支援事務
  • 事務處理可以用來維護資料庫的完整性,保證成批的 SQL 語句要麼全部執行,要麼全部不執行。
  • 一般來說,事務需要滿足4個條件(ACID):原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)、持久性(Durability)
  • mysql默認是自動提交事務的

原子性

一個事務(transaction)中的所有操作,要麼全部完成,要麼全部不完成,不會結束在中間某個環節。事務在執行過程中發生錯誤,會被回滾(Rollback)到事務開始前的狀態,就像這個事務從來沒有執行過一樣。

一致性

在事務開始之前和事務結束以後,資料庫的完整性沒有被破壞。這表示寫入的資料必須完全符合所有的預設規則,這包含資料的精確度、串聯性以及後續資料庫可以自發性地完成預定的工作。

隔離性

資料庫允許多個並發事務同時對其數據進行讀寫和修改的能力,隔離性可以防止多個事務並發執行時由於交叉執行而導致數據的不一致。事務隔離分為不同級別,包括讀未提交(Read uncommitted)、讀提交(read committed)、可重複讀(repeatable read)和串列化(Serializable)。

持久性

事務處理結束後,對數據的修改就是永久的,即便系統故障也不會丟失。

事務的隔離級別

隔離級別 臟讀(Dirty Read) 不可重複讀(NonRepeatable Read) 幻讀(Phantom Read)
未提交讀(Read uncommitted) 可能 可能 可能
已提交讀(Read committed) 不可能 可能 可能
可重複讀(Repeatable read) 不可能 不可能 可能
可串列化(Serializable ) 不可能 不可能 不可能

InnoDB默認是可重複讀級別的

  • ① 臟讀: 臟讀就是指當一個事務正在訪問數據,並且對數據進行了修改,而這種修改還沒有提交到資料庫中,這時,另外一個事務也訪問這個數據,然後使用了這個數據。
  • ② 不可重複讀:是指在一個事務內,多次讀同一數據。在這個事務還沒有結束時,另外一個事務也訪問該同一數據。那麼,在第一個事務中的兩次讀數據之間,由於第二個事務的修改,那麼第一個事務兩次讀到的的數據可能是不一樣的。這樣就發生了在一個事務內兩次讀到的數據是不一樣的,因此稱為是不可重複讀。
  • ③ 幻讀:第一個事務對一個表中的數據進行了修改,這種修改涉及到表中的全部數據行。同時,第二個事務也修改這個表中的數據,這種修改是向表中插入一行新數據。那麼,以後就會發生操作第一個事務的用戶發現表中還有沒有修改的數據行,就好象發生了幻覺一樣,幻讀是數據行記錄變多了或者少了。

簡單點總結下他們的區別:臟讀是指讀取了未修改完的記錄,不可重複讀指因為被其它事務修改了記錄導致某事務兩次讀取記錄不一致,而幻讀是指因為其它事務對錶做了增刪導致某事務兩次讀取的表記錄數不一致問題。

第1級別未提交讀(Read Uncommitted)

允許臟讀,也就是可能讀取到其他會話中未提交事務修改的數據

第2級別提交讀(Read Committed)

只能讀取到已經提交的數據。Oracle等多數資料庫默認都是該級別 (不重複讀)

第3級別可重複讀(Repeated Read)

可重複讀。在同一個事務內的查詢都是事務開始時刻一致的,InnoDB默認級別。在SQL標準中,該隔離級別消除了不可重複讀,但是還存在幻象讀

第4級別串列讀(Serializable)

完全串列化的讀,每次讀都需要獲得表級共享鎖,讀寫相互都會阻塞

mysql事務相關命令

查看mysql系統的事務隔離級別

mysql> SELECT @@global.tx_isolation;

查看mysql會話的事務隔離級別

mysql> SELECT @@tx_isolation;    -- 或    mysql> SELECT @@session.tx_isolation;  

設置系統的事務隔離級別

mysql> set global transaction isolation level read committed;

設置會話的事務隔離級別

mysql> set session transaction isolation level read committed;  -- 值可以分別為:READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ, SERIALIZABLE

查看autocommit變數

1:表示自動提交事務,0表示不自動提交事務

mysql> select @@autocommit;

設置mysql不自動提交事務

mysql> set autocommit = 0;

事務回滾

mysql> rollback;

顯示的開啟一個事務

mysql> start transaction;    -- 或    mysql> begin;

創建一個保存點

mysql> savepoint tem1;

顯示提交事務

mysql> commit;

資料