(九)MySQL基礎——事務以及隔離級別
一、事務
1、介紹:事務由單獨單元的一個或多個sql語句組成,在這個單元中,每個MySQL語句是相互依賴的。而整個單獨單元格作為一個不可分割的整體,如果單元中某條sql語句一旦執行失敗或產生錯誤,整個單元將會回滾。所有受到影響的資料將返回到事務開始以前的狀態。如果單元中的所有sql語句均執行成功,則事務被順利執行。
2、事務的(ACID)屬性
(1)原子性(Atomicity)
原子性是指事務是一個不可分割的工作單位,事務中的操作要麼都發生,要麼都不發生。
(2)一致性(Consistency)
事務必須使資料庫從一個一致性狀態變換到另外一個一致性狀態。
(3)隔離性(Isolation)
事務的隔離性是指一個事務的執行不能被其他事務干擾,即一個事務內部的操作及使用的資料對併發的其他事務是隔離的,併發執行的各個事務之間不能相互干擾。
(4)永續性(Durability)
永續性是指一個事務一旦被提交,它對資料庫中資料的改變就是永久性的,接下來的其他操作和資料庫故障不應該對其有任何影響。
3、事務的建立
(1)隱式事務:事務沒有明顯的開啟和結束的標記,比如INSERT、UPDATE、DELETE。(自動提交功能預設開啟)
(2)顯式事務:事務具有明顯的開啟和結束的標記,但前提是必須先設定自動提交功能為禁用。(只針對當前的事務有效,不會一直保持關閉狀態)
-- 關閉自動提交的功能
SET autocommit=0;
SHOW VARIABLES LIKE 'autocommit';
4、事務的使用步驟
步驟(1):開啟事務
SET autocommit=0;
-- 下面這個命令是可選的,不寫的話也會預設執行
START transaction;
步驟(2):編寫一組事務的sql語句(僅包括:SELECT、INSERT、UPDATE、DELETE)
-- 語句1; UPDATE account SET balance = 500 WHERE username="張無忌"; -- 語句2; UPDATE account SET balance = 1500 WHERE username="趙敏";
步驟(3):結束事務
-- 結束事務
commit;
-- 如果有異常則回滾事務
rollback;
演示結果:
5、事務併發問題
併發問題的原因:對於同時執行的多個事務,當這些事務訪問資料庫中相同的資料時,如果沒有采取必要的隔離機制,就會導致各種併發問題。
併發問題(1):髒讀
例如兩個事務T1,T2。T1讀取了已經被T2更新但還沒有被提交的欄位。之後,若T2回滾,T1讀取的內容就是臨時且無效的。
併發問題(2):不可重複讀
例如兩個事務T1,T2。T1讀取了一個欄位,然後T2更新了該欄位。之後,T1再次讀取同一個欄位,值就不同了。
併發問題(3):幻讀
例如兩個事務T1,T2。T1從一個表中讀取了一個欄位,然後T2在該表中插入了一些新的行。之後,如果T1再次讀取同一個表,就會多出幾行。
5、資料庫事務的隔離性
資料庫系統必須具有隔離併發執行各個事務的能力,使它們不會相互影響,避免各種併發問題。
6、一個事務與其他事務隔離的程度稱為隔離級別。資料庫規定了多種事務隔離級別,不同隔離級別對應不同的干擾程度,隔離級別越高,資料一致性就越好,但併發性越弱。
資料庫提供的4中事務隔離級別:
隔離級別 | 描述 |
READ UNCOMMITTED (讀未提交資料) |
允許事務讀取未被其他事務提供的變更。 髒讀、不可重複讀和幻讀的問題都會出現。 |
READ COMMITTED (讀已提交資料) |
只允許事務讀取已經被其他事務提交的變更。 可以避免髒讀,但不可重複讀和幻讀問題仍然可能存在。 |
PEPEATABLE READ (可重複讀) |
確保事務可以多次從一個欄位中讀取相同的值。 在這個事務持續期間,禁止其他事務對這個欄位進行更新。可以避免髒讀和不可重複讀,但幻讀的問題仍然存在。 |
SERIALIZABLE (序列化) |
確保事務可以從一個表中讀取相同的行。 在這個事務持續期間,禁止其他事務對該表執行插入,更新和刪除操作,所有併發問題都可以避免,但效能十分底下。 |
Oracle支援的2種事務隔離級別:READ COMMITED(預設是這個隔離級別,讀已提交資料) 和 SERIALIZABLE(序列化)。
Mysql支援以上4種事務隔離級別,其中預設隔離級別為:REPEATABLE READ(可重複讀)。
7、在MySQL中設定隔離級別
(1)每啟動一個mysql程式,就會獲得一個單獨的資料庫連線。每個資料庫連線都有一個全域性變數@@tx_isolation,表示當前的事務隔離級別。
(2)檢視當前的隔離級別:
SELECT @@tx_isolation;
(3)設定當前MySQL連線的隔離級別:
SET transaction isolation level read committed;
(4)設定資料庫系統的全域性的隔離級別:
SET global transaction isolation level read committed;
8、回滾點的演示
savepoint:節點名,用來設定儲存點
SET autocommit=0;
START TRANSACTION;
DELECT FROM account WHERE id=25;
-- 設定儲存點
SAVEPOINT a;
DELECT FROM account WHERE id=28;
-- 回滾到儲存點
ROLLBACK TO a;
9、DELETE和TRUNCATE在事務使用時的區別
DELETE刪除回滾後表還是存在的,然而TRUNCATE刪除表之後,哪怕回滾也不能恢復。也就是說delete是支援回滾的,也可以撤銷回滾;但是truncate不支援回滾。
-- 演示delete
SET autocommit=0;
START TRANSACTION;
DELETE TABLE account;
ROLLBACK;
SELECT * FROM account;
-- 演示truncate
SET autocommit=0;
START TRANSACTION;
TRUNCATE TABLE account;
ROLLBACK;
SELECT * FROM account;