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