-
- 事務概述
- 在 MySQL 中只有使用了 Innodb 數據庫引擎的數據庫或表才支持事務。
- 事務處理可以用來維護數據庫的完整性,保證成批的 SQL 語句要麼全部執行,要麼全部不執行。
- 事務用來管理DDL、DML、DCL操作,比如 insert,update,delete 語句,默認是自動提交的。
一般來說,事務是必須滿足4個條件(ACID):
- Atomicity(原子性)
- Consistency(穩定性、一致性)
- Isolation(隔離性)
- Durability(可靠性、持久性)
對於ACID的解釋如下:
- 原子性:構成事務的的所有操作必須是一個邏輯單元,要麼全部執行,要麼全部不執行。
- 穩定性(一致性):數據庫在事務執行前後狀態都必須是穩定的或者是一致的。
- 隔離性:事務之間不會相互影響。
- 可靠性(持久性):事務執行成功後必須全部寫入磁盤。
- MySQL事務支持
常見的操作有一下三個:
- BEGIN或START TRANSACTION;顯式地開啓一個事務;
- COMMIT;也可以使用COMMIT WORK,不過二者是等價的。COMMIT會提交事務,並使已對數據庫進行的所有修改稱爲永久性的;
- ROLLBACK;有可以使用ROLLBACK WORK,不過二者是等價的。回滾會結束用戶的事務,並撤銷正在進行的所有未提交的修改;
在 MySQL 命令行的默認設置下,事務都是自動提交的,即執行 SQL 語句後就會馬上執行 COMMIT 操作。因此要顯式地開啓一個事務務須使用命令 BEGIN 或 START TRANSACTION,或者執行命令 SET AUTOCOMMIT=0,用來禁止使用當前會話的自動提交。
創建表
插入數據
提交測試
回滾測試
-
- 事務併發問題
在事務的併發操作中可能會出現一些問題:
- 丟失更新:一個事務更新之後,另一個事務也更新了,但是第二個事務回滾了,則第一個事務也被回滾了。
- 髒讀:一個事務讀取到另一個事務未提交的數據。
- 不可重複讀:一個事務因讀取到另一個事務已提交的數據。導致對同一條記錄讀取兩次以上的結果不一致。update操作
- 幻讀:一個事務因讀取到另一個事務已提交的數據。導致對同一張表讀取兩次以上的結果不一致。insert、delete操作
- 事務隔離級別
爲了避免上面出現的幾種情況,在標準SQL規範中,定義了4個事務隔離級別,不同的隔離級別對事務的處理不同
- 四種隔離級別:
現在來看看MySQL數據庫爲我們提供的四種隔離級別(由低到高):
- Read uncommitted (讀未提交):最低級別,任何情況都無法保證。
- Read committed (讀已提交):可避免髒讀的發生。
- Repeatable read (可重複讀):可避免髒讀、不可重複讀的發生。
- Serializable (串行化):可避免髒讀、不可重複讀、幻讀的發生。
- 默認隔離級別
大多數數據庫的默認隔離級別是Read committed,比如Oracle、DB2等。
MySQL數據庫的默認隔離級別是Repeatable read。
- 如何查看和設置隔離級別:
在MySQL數據庫中查看當前事務的隔離級別:
select @@tx_isolation;
在MySQL數據庫中設置事務的隔離 級別:
set [glogal | session] transaction isolation level 隔離級別名稱;
set tx_isolation=’隔離級別名稱;’
- 注意事項:
隔離級別越高,越能保證數據的完整性和一致性,但是對併發性能的影響也越大。
對於多數應用程序,可以優先考慮把數據庫系統的隔離級別設爲Read Committed。它能夠避免髒讀取,而且具有較好的併發性能。儘管它會導致不可重複讀、幻讀這些併發問題,在可能出現這類問題的個別場合,可以由應用程序採用悲觀鎖或樂觀鎖來控制。