1. 程式人生 > 其它 >Mysql基礎:05.TCL 事務控制語言

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 隔離級別;