數據庫事務其實實現還是蠻復雜的,現在在單應用的情況下,簡單的多了。
隔離級別,用默認的;事務開啟提交:用Spring注解。這樣就已經滿足大多數場景了,甚至傳播行為也都是默認的。
而分布式的情況下也很少依賴數據庫分布式事務,也都是基于其他條件完成。
正因為這樣,很多人不去花心思了解,甚至八股文都沒有背全面,面試容易掛掉,記一記還是大有好處。
至于MVCC事務實現方式也比較重要,后面講。
1. 什么是數據庫的事務?(ACID特性)
數據庫事務是指一組數據庫操作,這些操作要么全部成功執行,要么全部失敗回滾,事務可以確保數據庫的一致性和完整性。
在MySQL中,事務是由一系列SQL語句組成的邏輯工作單元。事務具有以下四個特性(ACID特性):
-
原子性(Atomicity):事務中的所有操作要么全部執行成功,要么全部失敗回滾,不會出現部分執行的情況。
-
一致性(Consistency):事務執行前后,數據庫的狀態必須保持一致。如果事務執行失敗,數據庫會回滾到事務開始前的狀態。
-
隔離性(Isolation):事務的執行是相互隔離的,一個事務的操作不會被其他事務所干擾。事務之間的操作可以并發執行,但是結果必須與串行執行的結果一致。
-
持久性(Durability):一旦事務提交成功,其結果將永久保存在數據庫中,即使系統發生故障也不會丟失。
在MySQL中,可以使用 BEGIN
、COMMIT
和 ROLLBACK
語句來控制事務的開始、提交和回滾。通過使用事務,可以確保數據庫操作的一致性和完整性,同時提高并發性能。
之前存儲引擎篇反復提到了,目前Innodb支持事務,其他的存儲引擎不支持。
2. 數據庫的事務隔離級別有哪些?
MySQL數據庫的事務隔離級別有以下四種:
-
讀未提交(Read Uncommitted):事務中的修改可以被其他事務立即看到,可能會導致臟讀、不可重復讀和幻讀的問題。
-
讀已提交(Read Committed):事務中的修改只有在提交后才能被其他事務看到,可以避免臟讀的問題,但仍可能出現不可重復讀和幻讀的問題。
-
可重復讀(Repeatable Read):默認級別,事務中的查詢結果保持一致,即使其他事務對數據進行了修改,也不會被當前事務看到。可以避免臟讀和不可重復讀的問題,但仍可能出現幻讀的問題。
-
串行化(Serializable):事務串行執行,可以避免臟讀、不可重復讀和幻讀的問題,但會降低并發性能。
不同的隔離級別會對并發性能和數據一致性產生影響。隔離級別越高,數據一致性越好,但并發性能越差。而隔離級別越低,并發性能越好,但數據一致性可能會受到影響。因此,在選擇隔離級別時需要根據具體的業務需求和性能要求進行權衡。
3. Mysql默認是哪種隔離級別?
MySQL默認的隔離級別是可重復讀(REPEATABLE READ),通過下面sql可以查看當前隔離級別。
SELECT @@tx_isolation;
MySQL選擇可重復讀作為默認的隔離級別,主要是為了保證數據的一致性和避免臟讀、不可重復讀的情況。
對于幻讀來說,一般系統要求并沒有那么高。
也就是綜合了性能和數據安全性方面考慮,可重復讀是一個適用于大多數場景的情況。
4. 如何切換事務隔離級別?
在MySQL中,可以使用以下語句來切換事務隔離級別:
1. 查看當前的事務隔離級別:
SELECT @@tx_isolation;
2. 切換事務隔離級別:
SET SESSION TRANSACTION ISOLATION LEVEL <隔離級別>;
其中,<隔離級別>可以是以下幾種之一:
-
-
READ UNCOMMITTED:讀未提交
-
READ COMMITTED:讀已提交
-
REPEATABLE READ:可重復讀
-
SERIALIZABLE:串行化
-
例如,要將事務隔離級別切換為可重復讀:
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
3. 驗證事務隔離級別是否已切換:
SELECT @@tx_isolation;
需要注意的是,以上語句只會對當前會話生效,如果需要對全局生效,可以使用下面語句:
SET GLOBAL TRANSACTION ISOLATION LEVEL <隔離級別>
但是,一般情況下不建議修改全局的事務隔離級別,因為可能會對其他會話產生影響。
5. 哪些業務場景下要使用數據庫事務?
以下是一些生活常見的場景,可能需要使用事務:
實在太多了,根據項目說就可以了,這里隨便扯兩個常見的。
-
銀行轉賬:當一個用戶從一個賬戶向另一個賬戶轉賬時,需要確保資金的安全和一致性。使用事務可以保證在轉賬過程中,資金從一個賬戶減少,同時另一個賬戶增加,如果其中一個操作失敗,整個轉賬過程將被回滾。
-
在線支付:當用戶下單并支付時,需要確保訂單的支付和庫存的減少是原子操作。使用事務可以保證在支付過程中,訂單狀態更新為已支付,同時庫存減少,如果其中一個操作失敗,整個支付過程將被回滾。
這兩個場景都涉及到多個操作的原子性和一致性,使用事務可以確保這些操作要么全部成功,要么全部失敗。