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;