1. 程式人生 > >(九)MySQL基礎——事務以及隔離級別

(九)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;