mysql事務詳解
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;
資料
- Java問題收集
- mysql官方文件