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

MySQL——事務(Transaction)詳解

該部落格詳解MySQL中的事務

一、事務定義 Transaction 事務:一個最小的不可再分的工作單元;通常一個事務對應一個完整的業務(例如銀行賬戶轉賬業務,該業務就是一個最小的工作單元) 一個完整的業務需要批量的DML(insert、update、delete)語句共同聯合完成 事務只和DML語句有關,或者說DML語句才有事務。這個和業務邏輯有關,業務邏輯不同,DML語句的個數不同 二、轉賬操作理解事務 關於銀行賬戶轉賬操作,賬戶轉賬是一個完整的業務,最小的單元,不可再分————————也就是說銀行賬戶轉賬是一個事務 以下是銀行賬戶表t_act(賬號、餘額),進行轉賬操作 actno       balance 1           500 2           100 1 2 3 轉賬操作 update t_act set balance=400 where actno=1; update t_act set balance=200 where actno=2; 1 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)執行,標誌事務的開啟 1 結束標誌(提交或者回滾): -  提交:成功的結束,將所有的DML語句操作歷史記錄和底層硬碟資料來一次同步 -  回滾:失敗的結束,將所有的DML語句操作歷史記錄全部清空 1 2 七、事物與資料庫底層資料 在事物進行過程中,未結束之前,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) 1 2 3 4 5 6 7 8 9 10 11 12 回滾操作(事務失敗) 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) 1 2 3 4 5 6 7 8 9 10 11 12 九、事務四大特性之一————隔離性(isolation) 事物A和事物B之間具有一定的隔離性 隔離性有隔離級別(4個)  讀未提交:read uncommitted 讀已提交:read committed 可重複讀:repeatable read 序列化:serializable 1、 read uncommitted - 事物A和事物B,事物A未提交的資料,事物B可以讀取到 - 這裡讀取到的資料叫做“髒資料” - 這種隔離級別最低,這種級別一般是在理論上存在,資料庫隔離級別一般都高於該級別 1 2 3 2、read committed - 事物A和事物B,事物A提交的資料,事物B才能讀取到 - 這種隔離級別高於讀未提交 - 換句話說,對方事物提交之後的資料,我當前事物才能讀取到 - 這種級別可以避免“髒資料” - 這種隔離級別會導致“不可重複讀取” - Oracle預設隔離級別 1 2 3 4 5 6 3、repeatable read - 事務A和事務B,事務A提交之後的資料,事務B讀取不到 - 事務B是可重複讀取資料 - 這種隔離級別高於讀已提交 - 換句話說,對方提交之後的資料,我還是讀取不到 - 這種隔離級別可以避免“不可重複讀取”,達到可重複讀取 - 比如1點和2點讀到資料是同一個 - MySQL預設級別 - 雖然可以達到可重複讀取,但是會導致“幻像讀” 1 2 3 4 5 6 7 8 4、serializable - 事務A和事務B,事務A在操作資料庫時,事務B只能排隊等待 - 這種隔離級別很少使用,吞吐量太低,使用者體驗差 - 這種級別可以避免“幻像讀”,每一次讀取的都是資料庫中真實存在資料,事務A與事務B序列,而不併發 1 2 3 十、隔離級別與一致性關係

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

該選項值可以是:

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

•   例如: [mysqld] transaction-isolation = READ-COMMITTED 1 2 3 4 5 6 7 8 方式二 通過命令動態設定隔離級別  • 隔離級別也可以在執行的伺服器中動態設定,應使用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; 1 2 3 4 5 6 7 十二、隔離級別的作用範圍 •   事務隔離級別的作用範圍分為兩種:  –   全域性級:對所有的會話有效  –   會話級:只對當前的會話有效  •   例如,設定會話級隔離級別為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; 1 2 3 4 5 6 7 8 9 十三、檢視隔離級別 •   事務隔離級別的作用範圍分為兩種:  –   全域性級:對所有的會話有效  –   會話級:只對當前的會話有效  •   例如,設定會話級隔離級別為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;