在數據庫管理領域,事務是確保數據一致性和完整性的核心機制,它允許用戶將一系列操作視為一個不可分割的整體,要么全部成功執行,要么全部回滾。MySQL 和 Oracle 作為兩款廣泛使用的關系型數據庫管理系統,它們在事務處理方面既有共性,也存在諸多差異。接下來,我們將深入探討 MySQL 和 Oracle 事務的詳細內容,并對比兩者的區別。
MySQL事務詳解
事務的概念和特性
事務 是一組操作的集合,它是一個不可分割的工作單位,事務會把所有的操作作為一個整體一起向系統提交或撤銷操作請求,即這些操作要么同時成功,要么同時失敗。
? ? ? ? 注:默認MySQL的事務是自動提交的,也就是說,當執行一條DML語句,MySQL會立即隱式的提交事務。
? ? ? ? Oracle需要顯示提交事務,plsql軟件可通過設置自動提交
存儲引擎
? ? ? ? 存儲引擎就是存儲數據、建立索引、更新/查詢數據等技術的實現方式。存儲引擎是基于表的,而不是基于庫的,所以存儲引擎也可稱為表類型。
innoDB引擎
????????innoDB引擎是一種兼顧可靠性和高性能的通用存儲引擎。
特點:DML操作遵循ACID模型,支持事務行級鎖,提高并發訪問功能,支持外鍵foreign key約束,保證數據的完整性和正確性。
事務四大特性
- 原子性(Atomicity):事務中的操作是一個不可分割的最小單元,要么全部執行,要么全部不執行。例如,在銀行轉賬操作中,從賬戶 A 扣除金額和向賬戶 B 增加金額這兩個操作必須同時成功或失敗,不能出現 A 賬戶扣錢但 B 賬戶未到賬的情況。?
- 一致性(Consistency):事務執行前后,數據庫始終處于合法的狀態。假設數據庫中定義了某張表的字段必須滿足特定約束,如主鍵唯一、外鍵關聯正確等,事務執行后,這些約束依然要得到保證。?
- 隔離性(Isolation):多個事務并發執行時,一個事務的執行不能被其他事務干擾,每個事務都感覺像是在獨立使用數據庫。?
- 持久性(Durability):一旦事務提交,其對數據庫所做的修改就會永久保存,即使系統發生故障(如停電、宕機等)也不會丟失。
事務并發時存在的問題
臟讀(Dirty Read)
? ? ? ? 臟數據所指的就是未提交的數據,而臟讀是指在一個事務處理過程里讀取了另一個未提交的事務中的數據。
? ? ? ? 例:一個事務正對一條記錄做修改,在這個事務完成并提交之前,這條數據是處于待定狀態(可能提交也可能回滾),此時,第二個事務來讀取這條沒有提交的數據,并據此做進一步的處理,就會產生未提交的數據依賴關系。這種現象被稱為臟讀。
不可重復讀(Non-repeatable Read)
? ? ? ? 一個事務先后讀取同一條記錄,而事務在兩次讀取之間該數據被其他事務所修改,則兩次讀取的數據不同,我們稱為不可重復讀。
? ? ? ? 例:事務1在讀取某一數據,而事務2立馬修改了這個數據并提交事務給數據庫,事務1再次讀取該數據就得到了不同的結果,發生了不可重復讀。
? ? ? ? 不可重復讀和臟讀的區別:臟讀是某一個事務讀取了另一個事務未提交的事務,而不可重復讀則是在同一事務內讀取了前一事務提交的數據,即前一次讀到的數據是另一個事務提交前,后一次讀到的數據是提交后的。
幻讀(Phantom Read)
? ? ? ? 一個事物按相同的查詢條件重新讀取以前檢索過的數據,卻發現其他事務插入了滿足查詢跳到的新數據,這種現象稱為幻讀,幻讀是指當事務不是獨立執行時發生的一種現象。
? ? ? ? 幻讀和不可重復讀的區別:幻讀和不可重復讀都是讀取了另一條已經提交的事務(這點和臟讀不同),所不同的是不可重復讀查詢的都是同一個數據項,而幻讀針對的是一批數據整體。
四個隔離級別?
MySQL 支持四種事務隔離級別,不同的隔離級別會影響事務之間的并發行為和數據一致性:
- 讀未提交(Read Uncommitted):這是最低的隔離級別,雖然擁有超高的并發處理能力和很低的系統開銷,但很少用于實際應用。一個事務可以讀取另一個未提交事務的數據。這種隔離級別可能會出現臟讀、不可重復讀和幻讀問題 。?
- 讀已提交(Read Committed):一個事務只能讀取已提交事務的數據。它避免了臟讀,但仍可能出現不可重復讀和幻讀問題。Oracle 數據庫默認的隔離級別就是讀已提交。?
- 可重復讀(Repeatable Read):在一個事務內,多次讀取同一數據時,結果始終保持一致,即使其他事務對該數據進行了修改并提交。MySQL 默認的隔離級別是可重復讀,它通過多版本并發控制(MVCC)機制避免了臟讀和不可重復讀,但在某些情況下,幻讀問題依然可能存在 。?
- 可串行化(Serializable):這是最高的隔離級別,它通過強制事務串行執行,避免了所有的并發問題,包括臟讀、不可重復讀和幻讀。但由于事務只能一個接一個地執行,會極大地降低數據庫的并發性能。
隔離級別 | 臟讀 | 不可重復讀 | 幻讀 |
讀未提交 | √ | √ | √ |
讀已提交 | × | √ | √ |
可重復讀 | × | × | √ |
可串行化 | × | × |
Oracle 事務詳解
事務的概念與特性
Oracle 中的事務同樣遵循 ACID 特性,其核心概念與 MySQL 類似,將一組操作作為一個整體,保證數據的一致性和完整性。例如,在企業的訂單處理系統中,創建訂單、扣除庫存、更新客戶余額等操作會被封裝在一個事務內,確保整個業務流程的正確執行。
注:Oracle的事務特性和事務并發時存在的問題與MySQL相同。
存儲引擎
????????Oracle 的 “單一存儲引擎” 設計確保了數據在事務處理、數據分析、高可用性等場景下的一致性和兼容性。用戶可通過調整存儲參數(如塊大小、壓縮方式、分區策略)和選擇合適的數據組織方式(如表類型、索引結構),靈活應對不同的業務需求。這與 MySQL 等支持多存儲引擎(如 InnoDB、MyISAM)的數據庫形成鮮明對比,體現了 Oracle 在企業級數據管理中的一體化設計理念。
事務的隔離級別
Oracle支持兩種主要的事務隔離級別:
- 讀已提交(Read Committed):這是 Oracle 的默認隔離級別,它保證事務只能讀取其他事務已經提交的數據,避免了臟讀。在該隔離級別下,對于相同的查詢,每次執行可能會得到不同的結果(因為其他事務可能提交了新的數據修改),存在不可重復讀和幻讀問題。?
- 可串行化(Serializable):與 MySQL 的可串行化隔離級別類似,它通過對數據加鎖,使事務按照順序依次執行,從而避免了所有的并發問題。但這種方式會嚴重影響數據庫的并發性能,因此在實際應用中,除非對數據一致性要求極高且并發量較低的場景,一般較少使用 。此外,Oracle 還提供了一種基于多版本的讀一致性機制(Read Consistency),它允許事務在查詢數據時獲取到一個一致性的快照,即使在查詢過程中有其他事務修改了數據,也不會影響當前事務的查詢結果,在一定程度上緩解了并發讀取時的數據不一致問題 。
隔離級別 | 臟讀 | 不可重復讀 | 幻讀 |
---|---|---|---|
讀已提交(默認) | 否 | 是 | 是 |
可串行化 | 否 | 否 | 否 |
事務操作
查看MySQL支持哪些引擎。
show engines; -- 當前MySQL版本支持哪些引擎
注:innoDB支持事務,myisam、memory等不支持事務
查看MySQL當前默認的存儲引擎。
show variables like '%storage_engine%';
注:MySQL 5.5版本前,默認存儲引擎是MyISAM
? ? ? ? ?MySQL 5.5版本后,默認存儲引擎是innoDB
顯示自動提交事務的狀態(insert、update、delete)
show variables like 'autoconmit';
開啟事務
-- MySQL
set @@autocommit=0 ; -- 將自動提交事務關閉,只對當前對話有效
set @@autocommit=1 ; -- 設置自動提交事務begin; -- 開啟事務
start transaction; -- 開啟事務-- Oracle
-- 執行DML語句,隱式開啟事務
UPDATE employees SET salary = salary * 1.1 WHERE department_id = 10;
提交事務
-- MySQL
select @@autoconmit; -- 查詢結果為1自動提交
set @@autocommit=0 ; -- 為0手動提交commit; -- 提交事務(成功)
rollback; -- 回滾事務(失敗)-- Oracle
-- 查詢自動提交事務
SHOW AUTOCOMMIT;
-- 輸出:AUTOCOMMIT OFF(關閉自動提交) 或 AUTOCOMMIT ON(開啟自動提交)-- 設置自動提交格式
SET AUTOCOMMIT ON; -- 開啟自動提交(每條SQL執行后自動COMMIT)
SET AUTOCOMMIT OFF; -- 關閉自動提交(默認行為)
-- 事務的提交與回滾
UPDATE employees SET salary = salary*1.1 WHERE department_id = 10;
-- 執行多個DML語句...COMMIT; -- 提交所有更改
ROLLBACK; -- 回滾所有更改
MySQL和Oracle事務區別總結
隔離級別支持?
MySQL 支持四種完整的事務隔離級別,而 Oracle 主要支持讀已提交和可串行化兩種隔離級別。雖然 Oracle 也有讀一致性機制,但與 MySQL 的隔離級別概念有所不同。MySQL 的可重復讀隔離級別通過 MVCC 在一定程度上解決了幻讀問題,而 Oracle 的讀已提交隔離級別下幻讀問題依然較為突出,需要通過其他機制(如顯式加鎖)來處理 。
事務控制語句?
雖然兩者都有開啟事務、提交事務和回滾事務的語句,但在具體使用和功能上存在細微差別。例如,MySQL 的 START TRANSACTION 和 BEGIN 功能基本相同,都用于顯式開啟事務;而 Oracle 的 BEGIN 通常用于開啟一個匿名塊,隱式開啟事務 。在保存點的使用上,Oracle 提供了更豐富的語句來管理保存點,如 ROLLBACK TO SAVEPOINT AND RELEASE SAVEPOINT ,相比之下,MySQL 在保存點管理方面的功能相對簡單 。
性能表現?
在事務處理性能方面,由于 MySQL 的隔離級別和鎖機制更加靈活,在一些高并發且對數據一致性要求不是極高的場景下,MySQL 可能具有更好的并發性能。而 Oracle 的事務處理機制更側重于數據的一致性和完整性,在復雜的企業級應用中,尤其是對數據準確性要求嚴格的場景下,Oracle 能夠提供更可靠的事務保障,但在高并發場景下,其性能可能會受到一定影響 。?
綜上所述,MySQL 和 Oracle 在事務處理方面各有特點。在實際應用中,需要根據具體的業務需求、數據一致性要求和并發量等因素,選擇合適的數據庫及事務處理策略。
求點贊、求關注、求收藏!!!會繼續發布關于數據開發方面的博客!