天天看點

一文帶你明白“MySQL事務(transaction)”

目錄

  ​​1、什麼是事務?​​​   ​​2、和事務相關的語句隻有這3個DML語句:insert、delete、update​​   ​​3、假設所有的業務都能使用1條DML語句搞定,還需要事務機制嗎?​​   ​​4、事務的原理​​   ​​5、事務的四大特性:ACID​​   ​​6、關于事務之間的隔離性​​   ​​7、示範事務的隔離級别(示範資料自己造一些)​​

1、什麼是事務?

一文帶你明白“MySQL事務(transaction)”

一個事務是一個完整的業務邏輯單元,不可再分。

比如:銀行賬戶轉賬,從A賬戶向B賬戶轉賬10000,需要執行兩條update語句:

update t_act set balance=balance-10000 where actno='act-001';
update t_act set balance=balance+10000 where actno='act-0021';      

以上兩條DML語句必須同時成功,或者同時失敗,不允許出現一條成功,一條失敗。

要想保證以上的兩條DML語句,同時成功或者同時失敗,那麼就需要使用資料庫的

“事務機制”。

2、和事務相關的語句隻有這3個DML語句:insert、delete、update

“為什麼隻有這3個DML語句:insert、delete、update?”

因為它們這三個語句都是和資料庫表中的"資料相關"的。事務的存在是為了保證資料的完整性,安全性。

3、假設所有的業務都能使用1條DML語句搞定,還需要事務機制嗎?

不需要事務。

但實際情況不是這樣的,通常一個事兒(“事務”)需要多條DML語句共同聯合完成。

4、事務的原理

一文帶你明白“MySQL事務(transaction)”

注意:

一旦送出事務,就會把曆史操作持久化到硬碟上去,持久化完成後,清空曆史記錄。

一旦復原事務,就會把曆史記錄直接清空掉,而不持久化到硬碟中。

事務操作,還可以設計儲存點:了解。

5、事務的四大特性:ACID

一文帶你明白“MySQL事務(transaction)”

事務包括四大特性:ACID

A原子性:事務是最小的工作單元,不可再分。

C一緻性:事務必須保證多條DML語句,同時成功或者同時失敗。

I隔離性:事務A與事務B之間具有隔離。

D持久性:持久性指的是最終資料必須持久化到硬碟檔案中,事務才算成功結束。

下面對上述事務四大特性,進行一個更為詳細的說明

“原子性”:一組操作要麼都成功,要麼都失敗,這一組操作是不可拆分的。

“一緻性”:事務發生前後,資料總額仍然是比對的。模拟一個人給另外一個人轉賬來說,轉賬之前,2人的金額總和為400;轉賬以後,2人的金額總額仍為400。

“隔離性”:所有操作沒有執行完畢之前,其它會話視窗不能看見中間資料的改變過程,隻有目前視窗可以看見資料改變過程。

“持久性”:一旦commit送出後,事務産生的影響就不能夠撤銷了,已經實實在在把資料修改了。

6、關于事務之間的隔離性

"事務的隔離性存在隔離級别,理論上隔離級别包括4個"
隔離級别一般都是從2級、3級起步,1級一般用不上。
1)第一級别:讀未送出(read uncommitted)
   對方的事務還沒有送出,目前事務可以讀取到對方為送出的資料。
   讀未送出存在的問題:"髒讀現象",表示讀到了髒資料。
   "髒讀":指的是一個事務正在修改資料,但是這種修改并沒有送出到資料庫。
而另一個事務,通路到了該資料,此時這個資料屬于【髒資料】,因而叫髒讀。

2)第二級别:讀已送出(read committed)
   對方事務送出後的資料,我方可以讀取到。
   這種隔離級别解決了:髒讀現象沒有了。
   讀已送出存在的問題:不可重複讀。
   
3)第三級别:可重複讀(repeatable read)
   這種隔離級别解決了:不可重複讀問題。
   這種級别存在的問題:讀取到的資料是幻想,即讀取的是備份資料。
   
4)第四級别:序列化讀/串行化讀(serializable)
   解決了所有問題。
   但是效率低,需要事務排隊。
   
"需要注意的是"      

7、示範事務的隔離級别(示範資料自己造一些)

1)示範事務之前,需要掌握的知識點。
1)mysql預設情況下,事務是自動送出的。
2)什麼是自動送出?
   隻要是執行任意一條DML語句,則自動送出一次。
   是以,在示範事務之前,必須先關閉自動送出。
   "關閉自動送出語句":start transaction;
    
3)"示範事務需要知道的3條指令:"
   -- 關閉自動送出事務功能。
   start transaction;
  -- 送出事務。
  commit;
  -- 復原事務,隻能復原到上一次的送出點。
  rollback;      
2)設定全局事務隔離級别。
"設定全局事務隔離級别,設定完成後,退出重新登陸。"
-- 設定第一級别
set global transaction isolation level read uncommitted;
-- 設定第二級别
set global transaction isolation level read committed;
-- 設定第三級别(系統預設的事務級别,不用設定)
set global transaction isolation level repeatable read;
--設定第四級别
set global transaction isolation level serializable;

"檢視全局事務隔離級别"
mysql> select @@global.tx_isolation;
+-----------------------+
| @@global.tx_isolation |
+-----------------------+
| REPEATABLE-READ       |
+-----------------------+
1 row in set, 1 warning (0.00 sec)      
3)示範讀未送出。

首先,設定全局事務隔離級别。

一文帶你明白“MySQL事務(transaction)”

下面進行正式的示範:

一文帶你明白“MySQL事務(transaction)”
4)示範讀已送出

首先,設定全局事務隔離級别。

一文帶你明白“MySQL事務(transaction)”

下面進行正式的示範:

一文帶你明白“MySQL事務(transaction)”
5)示範可重複讀

首先,設定全局事務隔離級别。

一文帶你明白“MySQL事務(transaction)”

下面進行正式的示範:

一文帶你明白“MySQL事務(transaction)”
這個需要注意:
    這裡示範的是"可重複讀",我們在右邊視窗示範事務的一些列過程,左邊視窗
根本無法讀取,左邊視窗讀取到的,始終是原始資料的備份資料。
    怎麼了解呢?
    你别忘記了,左邊視窗,也是開啟事務功能了的,start transaction;隻要
是左邊這個視窗的事務功能,沒有結束(commit或者rollback都可以結束事務),那
麼左邊視窗讀取到的,始終是原始資料的備份資料,這就是我們所說的"幻想"。任
憑右邊黑視窗中做了任何改變,就算你也送出了事務,我左邊視窗,就是看不到。
    "左邊黑視窗,要怎麼才可以看見這個變化呢?"      
6)示範序列化讀

首先,設定全局事務隔離級别。

一文帶你明白“MySQL事務(transaction)”

下面進行正式的示範:

第一幅圖:

一文帶你明白“MySQL事務(transaction)”