1. 程式人生 > 實用技巧 >MySQL基礎-19TCL語言(事務控制語言)-事務

MySQL基礎-19TCL語言(事務控制語言)-事務

宣告:此MySQL基礎學習源自尚矽谷。(推薦)b站官方連結:https://www.bilibili.com/video/BV1xW411u7ax?p=1

Transaction Control Language 事務控制語言

事務

一個或一組sql語句組成一個執行單元,這個執行單元要麼全部執行,要麼全部不執行。

案例:轉賬

賬戶表:

張三丰 1000
郭襄 1000

虛擬碼:

update 表 set 張三丰的餘額=500 where name='張三丰' # 執行成功
-- 出錯
update 表 set 郭襄的餘額=1500 where name='郭襄' # 執行失敗

事務:

事務由單獨單元的一個或多個SQL語句組成,在這個單元中,每個MySQL語句是相互依賴的。而整個單獨單元作為一個不可分割的整體,如果單元中某條SQL語句一旦執行失敗或產生錯誤,整個單元將會回滾。所有受到影響的資料將返回到事務開始以前的狀態;如果單元中的所有SQL語句均執行成功,則事務被順利執行。

儲存引擎(表型別)

-- 顯示MySQL引擎
SHOW ENGINES;
1.在MySQL中的資料用各種不同的技術儲存在檔案(或記憶體)中。
2.通過show engines; 來檢視MySQL支援的儲存引擎。
3.在MySQL中用的最多的儲存引擎有:innodb、myisam、memory等。其中innodb支援事務,而myisam、memory等不支援事務。
(5.5版本之前預設的儲存引擎myisam)

事務的ACID特性⭐

1.原子性(Atomicity):指事務是一個不可再分割的工作單位,事務中的操作要麼都執行,要麼都不執行。
2.一致性(Consistency):事務必須使資料庫從一個一致性狀態變換到另外一個一致性狀態。
如:轉賬前總金額2000,轉賬後總金額依然2000

3.隔離性(Isolation):指一個事務的執行不能被其他事務的干擾,即一個事務內部的操作及使用的資料對併發的其他事務是隔離的,併發執行的各個事物之間不能互相干擾。
4.永續性(Durability):指一個事務一旦提交,它對資料庫中資料改變就是永久性的,接下來的其他操作和資料庫故障不應該對其有任何影響。

事務的建立

DDL語言沒有事務

隱式事務:事務沒有明顯的開啟和結束的標記
比如:insert、update、delete語句
	delete from 表 where id =1;

顯式事務:事務具有明顯的開啟和結束的標記
前提:必須先設定自動提交功能為禁用
	set autocommit=0; # 只針對當前會話有效

步驟1:開啟事務
set autocommit=0; # 必須的,預設開啟事務
start transaction; # 可選的,在客戶端中需要加,在終端視窗中可以不加

步驟2:編寫事務中的sql語句(select insert update delete)
    語句1;
    語句2;
    ...

步驟3:結束事務
commit; # 提交事務
或者
rollback; # 回滾事務

-- 顯示系統變數,檢視自動提交功能狀態
SHOW VARIABLES LIKE 'autocommit';

事務的隔離級別

事務的併發問題是如何產生的?

多個事務 同時 操作 同一個資料庫的相同資料時。
對於同時執行的多個事務,當這些事務訪問資料庫中相同的資料時,如果沒有采取必要的隔離機制,就會導致各種併發問題。

併發問題有哪些?

髒讀:對於兩個事務T1、T2,T1讀取了已經被T2更新但還沒有被提交的欄位之後,若T2回滾,T1讀取的內容就是臨時且無效的。

不可重複讀:對於兩個事務T1、T2,T1讀取了一個欄位,然後T2更新了該欄位之後,T1再次讀取同一個欄位,值就不同了。

幻讀:對於兩個事務T1、T2,T1從一個表中讀取了一個欄位,然後T2在該表中插入了一些新的行之後,如果T1再次讀取同一個表,就會多出幾行。
通過設定隔離級別來解決併發問題

資料庫事務的隔離性:

資料庫系統必須具有隔離併發執行各個事務的能力,使它們不會相互影響,避免各種併發問題。
一個事務與其他事務隔離的程度稱為隔離級別,資料庫規定了多種事務隔離級別,不同隔離級別對應不同的干擾程度,隔離級別越高,資料一致性就越好,但併發性越弱。
隔離級別 描述
READ UNCOMMITTED(讀未提交資料) 允許事務讀取未被其他事務提交的變更,髒讀,不可重複讀和幻讀的問題都會出現
READ COMMITED(讀已提交資料) 只允許事務讀取已經被其他事務提交的變更,可以避免髒讀,但不可重複讀和幻讀問題仍然可能出現
REPEATABLE READ(可重複讀) 確保事務可以多次從一個欄位中讀取相同的值,在這個事務持續期間,禁止其他事務對這個欄位進行更新,可以避免髒讀和不可重複讀,但幻讀的問題仍然存在
SERIALIZABLE(序列化) 確保事務可以從一個表中讀取相同的行,在這個事務持續期間禁止其他事務對該表執行插入,更新和刪除操作,所有併發問題都可以避免,但效能十分低下
read uncommitted /riːd/ /ˌʌn kəˈmɪ tɪ d/ 讀未提交資料
read commiter /riːd/ /kəˈmɪ tɪ d/ 讀已提交資料
repeatable read /rɪˈpiːtə bl/ /riːd/ 可重複讀
serializable /ˈsɪərɪəlaɪzəbl/ 序列化
Oracle支援的2種事務隔離級別:READ COMMITED,SERIALIZABLE。
Oracle預設的事務隔離級別為:READ COMMITED

MySQL支援4種事務隔離級別,MySQL預設的事務隔離級別為:REPEATABLE READ(可重複讀)
每啟動一個MySQL程式,就會獲得一個單獨的資料庫連線,每個資料庫連線都有一個全域性變數@@tx_isolation,表示當前的事務的隔離級別。(navicat的查詢/SQLyog的詢問都並不是新連線)
cmd:mysql -u使用者名稱 -p密碼(每個cmd屬於新連線)

-- 檢視當前隔離級別
select @@tx_isolation;
-- 設定當前連線的隔離級別
set session transaction isolation level 隔離級別;
-- 設定資料庫系統全域性的隔離級別
set global transaction isolation level read committed;

設定儲存點

savepoint 節點名; # 設定儲存點
-- 只能搭配rollback,不能搭配commit。
# 演示savepoint 的使用
SET autocommit=0;
START TRANSACTION;
DELETE FROM account WHERE id=25; # 語句1
SAVEPOINT a; # 設定儲存點  儲存點名為a
DELETE FROM account WHERE id=28;  # 語句2
ROLLBACK TO a; # 回滾到儲存點

SELECT * FROM account;

事務對於delete和truncate的處理的區別

-- 演示delete
set autocommit=0;
start transaction;
delete from account;
rollback;

-- 演示truncate
set autocommit=0;
start transaction;
truncate table account;
rollback;

-- truncate操作不支援回滾,即使回滾也不能恢復資料,delete可以