1. 程式人生 > >MySQL——事務(Transaction)

MySQL——事務(Transaction)

轉載地址:https://blog.csdn.net/w_linux/article/details/79666086

一、事務定義
Transaction

事務:一個最小的不可再分的工作單元;通常一個事務對應一個完整的業務(例如銀行賬戶轉賬業務,該業務就是一個最小的工作單元)
一個完整的業務需要批量的DML(insert、update、delete)語句共同聯合完成
事務只和DML語句有關,或者說DML語句才有事務。這個和業務邏輯有關,業務邏輯不同,DML語句的個數不同

  


二、轉賬操作理解事務
關於銀行賬戶轉賬操作,賬戶轉賬是一個完整的業務,最小的單元,不可再分————————也就是說銀行賬戶轉賬是一個事務
以下是銀行賬戶表t_act(賬號、餘額),進行轉賬操作

actno balance
1 500
2 100

  


轉賬操作

update t_act set balance=400 where actno=1;
update t_act set balance=200 where actno=2;

  


以上兩臺DML語句必須同時成功或者同時失敗。最小單元不可再分,當第一條DML語句執行成功後,並不能將底層資料庫中的第一個賬戶的資料修改,只是將操作記錄了一下;這個記錄是在記憶體中完成的;當第二條DML語句執行成功後,和底層資料庫檔案中的資料完成同步。若第二條DML語句執行失敗,則清空所有的歷史操作記錄,要完成以上的功能必須藉助事務

三、事務四大特徵(ACID)

原子性(A):事務是最小單位,不可再分
一致性(C):事務要求所有的DML語句操作的時候,必須保證同時成功或者同時失敗
隔離性(I):事務A和事務B之間具有隔離性
永續性(D):是事務的保證,事務終結的標誌(記憶體的資料持久到硬碟檔案中)

  


四、關於事務的一些術語

開啟事務:Start Transaction
事務結束:End Transaction
提交事務:Commit Transaction
回滾事務:Rollback Transaction

  


五、和事務相關的兩條重要的SQL語句(TCL)

commit:提交
rollback:回滾

  


六、事務開啟的標誌?事務結束的標誌?
開啟標誌:

- 任何一條DML語句(insert、update、delete)執行,標誌事務的開啟

  


結束標誌(提交或者回滾):

- 提交:成功的結束,將所有的DML語句操作歷史記錄和底層硬碟資料來一次同步
- 回滾:失敗的結束,將所有的DML語句操作歷史記錄全部清空

  


七、事物與資料庫底層資料

在事物進行過程中,未結束之前,DML語句是不會更改底層資料,只是將歷史操作記錄一下,在記憶體中完成記錄。只有在事物結束的時候,而且是成功的結束的時候,才會修改底層硬碟檔案中的資料

  

八、在MySQL中,事務提交與回滾
在MySQL中,預設情況下,事務是自動提交的,也就是說,只要執行一條DML語句就開啟了事物,並且提交了事務

以上的自動提交機制是可以關閉的
對t_user進行提交和回滾操作
提交操作(事務成功)
start transaction
DML語句
commit

 

mysql> start transaction;#手動開啟事務
mysql> insert into t_user(name) values('pp');
mysql> commit;#commit之後即可改變底層資料庫資料
mysql> select * from t_user;
+----+------+
| id | name |
+----+------+
| 1 | jay |
| 2 | man |
| 3 | pp |
+----+------+
3 rows in set (0.00 sec)

  


回滾操作(事務失敗)
start transaction
DML語句
rollback

mysql> start transaction;
mysql> insert into t_user(name) values('yy');
mysql> rollback;
mysql> select * from t_user;
+----+------+
| id | name |
+----+------+
| 1 | jay |
| 2 | man |
| 3 | pp |
+----+------+
3 rows in set (0.00 sec)

  


九、事務四大特性之一————隔離性(isolation)
事物A和事物B之間具有一定的隔離性
隔離性有隔離級別(4個)
讀未提交:read uncommitted
讀已提交:read committed
可重複讀:repeatable read
序列化:serializable
1、 read uncommitted

- 事物A和事物B,事物A未提交的資料,事物B可以讀取到
- 這裡讀取到的資料叫做“髒資料”
- 這種隔離級別最低,這種級別一般是在理論上存在,資料庫隔離級別一般都高於該級別

  


2、read committed

- 事物A和事物B,事物A提交的資料,事物B才能讀取到
- 這種隔離級別高於讀未提交
- 換句話說,對方事物提交之後的資料,我當前事物才能讀取到
- 這種級別可以避免“髒資料”
- 這種隔離級別會導致“不可重複讀取”
- Oracle預設隔離級別

  


3、repeatable read

- 事務A和事務B,事務A提交之後的資料,事務B讀取不到
- 事務B是可重複讀取資料
- 這種隔離級別高於讀已提交
- 換句話說,對方提交之後的資料,我還是讀取不到
- 這種隔離級別可以避免“不可重複讀取”,達到可重複讀取
- 比如1點和2點讀到資料是同一個
- MySQL預設級別
- 雖然可以達到可重複讀取,但是會導致“幻像讀”

  


4、serializable

- 事務A和事務B,事務A在操作資料庫時,事務B只能排隊等待
- 這種隔離級別很少使用,吞吐量太低,使用者體驗差
- 這種級別可以避免“幻像讀”,每一次讀取的都是資料庫中真實存在資料,事務A與事務B序列,而不併發

  


十、隔離級別與一致性關係

十一、設定事務隔離級別
方式一
可以在my.ini檔案中使用transaction-isolation選項來設定伺服器的預設事務隔離級別。

該選項值可以是:

– READ-UNCOMMITTED
– READ-COMMITTED
– REPEATABLE-READ
– SERIALIZABLE

• 例如:
[mysqld]
transaction-isolation = READ-COMMITTED

  

方式二
通過命令動態設定隔離級別
• 隔離級別也可以在執行的伺服器中動態設定,應使用SET TRANSACTION ISOLATION LEVEL語句。
• 其語法模式為:

SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL <isolation-level>
其中的<isolation-level>可以是:
– READ UNCOMMITTED
– READ COMMITTED
– REPEATABLE READ
– SERIALIZABLE
• 例如: SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;

  


十二、隔離級別的作用範圍

• 事務隔離級別的作用範圍分為兩種: 
– 全域性級:對所有的會話有效 
– 會話級:只對當前的會話有效 
• 例如,設定會話級隔離級別為READ COMMITTED :
mysql> SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
或:
mysql> SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
• 設定全域性級隔離級別為READ COMMITTED : 
mysql> SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;

  


十三、檢視隔離級別

• 事務隔離級別的作用範圍分為兩種: 
– 全域性級:對所有的會話有效 
– 會話級:只對當前的會話有效 
• 例如,設定會話級隔離級別為READ COMMITTED :
mysql> SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
或:
mysql> SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
• 設定全域性級隔離級別為READ COMMITTED : 
mysql> SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;