Mysql基礎:05.TCL 事務控制語言
TCL:事務控制語言
TCL(Transaction Control Language)
一、事務
1. 事務的概念
一個或一組sql語句組成一個執行單元,這個執行單元要麼全部執行,要麼全部不執行
2. 事務的特性(ACID)
- 原子性(Atomicity):一個事務不可再分割,要麼都執行要麼都不執行
- 一致性(Consistency):一個事務執行會使資料從一個一致狀態切換到另外一個一致狀態
- 隔離性(Isolation):一個事務的執行不受其他事務的干擾
- 永續性(Durability):一個事務一旦提交,則會永久的改變資料庫的資料.
3. 事務的使用步驟
-
隱式(自動)事務:沒有明顯的開啟和結束,本身就是一條事務可以自動提交,比如insert、update、delete。autocommit為ON時則表示處於自動事務狀態
#在MySQL中檢視autocommit狀態 SHOW VARIABLES LIKE 'autocommit';
-
顯式事務:事務具有明顯的開啟和結束的標記;前提:必須先設定自動提交功能為禁用(將autocommit設定為OFF)
3.1 事務的提交
事務語句一般只是基本的增刪改查:select insert update delete,對於庫表的操作,例如 alter drop等,不將其作為事務語句
#步驟1:開啟事務 set autocommit=0;#設定自動提交功能為禁用 start transaction;#可選的 #步驟2:編寫事務中的sql語句(select insert update delete) 語句1; 語句2; ... #步驟3:結束事務,一般為提交事務或者回滾事務 commit;提交事務
#開啟事務
SET autocommit=0;
START TRANSACTION;
#編寫一組事務的語句
INSERT INTO major VALUES(1,'java');
INSERT INTO major VALUES(2,'c++');
#結束事務
commit;
值得注意的是更新和提交是兩個概念。上面的sql語句中,執行commit語句之前,兩條資料只是暫時放在記憶體中,只有當執行完commit語句後,磁碟中的資料庫才發生更改。
那麼如果結束事務的語句不是commit,而是rollback回滾,則這兩條資料並不會存到磁碟中,即資料庫不會發生改變
3.2 事務的回滾
3.2.1 基本操作
在結束事務時將commit改為rollback即可
#開啟事務
SET autocommit=0;
START TRANSACTION;
#編寫一組事務的語句
INSERT INTO major VALUES(1,'java');
INSERT INTO major VALUES(2,'c++');
#結束事務
commit;
#rollback;
3.2.2 儲存點
儲存點(回滾點)savepoint:儲存事務狀態的節點
#設定儲存點
SAVEPOINT 儲存點名;
#回滾到指定儲存點
ROLLBACK TO 儲存點名;
下面的事務結束後,id為2的不會刪除,1會刪除
SET autocommit=0;
DELETE FROM major WHERE id = 1;
SAVEPOINT a;#設定儲存點a
DELETE FROM major WHERE id = 2;
ROLLBACK TO a;#回滾到儲存點a
3.2.3 delete和truncate在回滾時候的區別
delete刪除可以回滾,truncate刪除不可以回滾
#delete刪除
SET autocommit=0;
START TRANSACTION;
DELETE FROM major;#執行完不會刪
ROLLBACK;
#truncate刪除
SET autocommit=0;
START TRANSACTION;
TRUNCATE TABLE major;#執行完會刪
ROLLBACK;
SELECT * FROM major;
二、併發事務
1. 併發事務的概念
多個事務同時操作同一個資料庫的相同資料時,稱為併發事務,如果沒有采取必要的隔離機制,容易出現事務的併發問題
2. 常見的併發問題
- 髒讀:一個事務讀取了其他事務更新但沒有提交的資料
- 幻讀:一個事務讀取了其他事務插入或刪除但沒有提交的資料
- 不可重複讀:一個事務多次讀取,結果不一樣
3. 事務的隔離性與隔離級別
資料庫事務的隔離性: 資料庫系統必須具有隔離併發執行各個事務的能力,使它們不會相互影響。 因此需要設定隔離級別來解決併發問題
隔離級別:一個事務與其他事務隔離的程度稱為隔離級別。 資料庫規定了多種事務隔離級別,不同隔離級別對應不同的干擾程度,隔離級別越高,資料一致性就越好,但併發性越弱。下表為隔離級別與能否解決併發問題的對應關係
隔離級別 | 髒讀 | 不可重複讀 | 幻讀 |
---|---|---|---|
read uncommitted:讀未提交(允許事務讀取未被其它事務提交的變更) | × | × | × |
read committed:讀已提交(只允許事務讀取已經被其它事務提交的變更,只能 避免髒讀) | √ | × | × |
repeatable read:可重複讀(確保事務多次從一個欄位中讀取相同的值,在這個事務持續期間,禁止其他事務對這個欄位進行更新,可以避免髒讀和不可重複讀) | √ | √ | × |
serializable:序列化(確保事務可以從一個表中讀取相同的行,在這個事務持續期間,禁止其他事務對該表執行插入、更新和刪除操作,所有併發問題都可以避免,但效能低下) | √ | √ | √ |
(Oracle 支援的2 種事務隔離級別:read committed(預設), serializable;MySQL支援4種隔離級別,預設為repeatable read)
每啟動一個MySQL程式,就會獲得一個單獨的資料庫連線,每個連線都有一個全域性變數@@transaction_isolation
,表示當前的事務隔離級別
#檢視當前MySQL連線的隔離級別
select @@transaction_isolation; # 舊版本可以用別名tx_isolation,新版本不可以
#設定當前MySQL連線的隔離級別
#set session transaction isolation level 隔離級別;
set session transaction isolation level read uncommitted;
#設定整個資料庫系統全域性的隔離級別,設定完需要重啟
set global transaction isolation level 隔離級別;