一、事務的概念:
什么是"事務":它是數據庫中的概念。它是指一個具體的業務,在數據庫中要多條語句才能完成,例如:
銀行轉賬的業務:張三給李四轉賬1000元;
1).給張三賬戶減少1000元;
2).給李四賬戶增加1000元;
這時我們程序至少要發送兩條SQL語句,這樣中間就會有時間差,在這個時間差內如果程序或者數據庫軟件發生問題,而一條SQL已經被執行,再次重啟后,由于只發生了一條修改,第二條沒有被執行,這樣數據的整體就不準確了。
這就要求數據庫軟件必須具有一種能力:將多條SQL語句看成是一個整體,要么全部執行成功;如果有一條失敗,全部失敗,這種處理能力就叫:事務處理。
二、獨立操作數據庫軟件來操作事務:
1、查看當前數據庫的"事務處理"方式:
show variables like 'autocommit';
查詢結果:
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit | ON | 自動提交:開啟(關閉)
+---------------+-------+
自動提交(開啟):每條SQL語句作為一個獨立的事務,多條SQL語句之間沒有任何關系。
每條SQL發送到服務器會被立即執行。這種情況下,不能滿足我們的需要。
2、操作事務的兩種方式:
A).關閉自動提交:
1).關閉自動提交:
set autocommit = off;
2).發送SQL語句
update ....
delete ....
insert ....
select ....
3).提交/回滾
commit;//提交
rollback;//回滾
注意:一旦提交,會將這之前所有緩存的SQL語句全部執行,并且立即修改數據庫,到這里,這個事務就算結束,之后再發送的SQL語句就作為另一個事務。
一旦提交后,不能在回滾,一旦回滾后,也不能再提交了。
B).在"自動提交"狀態下,開啟一個"臨時事務"
1).開啟臨時事務:
start transaction;
2).發送SQL語句:
update ...
insert ...
delete ...
select ...
3).提交/回滾
commit;//提交
rollback;//回滾;
注意:一旦提交/回滾后,這個事務就整體結束,立即恢復到"自動提交"狀態(每條SQL語句都是一個獨立事務)。
三、事務的特性ACID:
1、原子性(Atomicity)原子性是指事務是一個不可分割的工作單位,事務中的操作要么都發生,要么都不發生。
2、一致性(Consistency)事務前后數據的完整性必須保持一致。
3、隔離性(Isolation)事務的隔離性是指多個用戶并發訪問數據庫時,一個用戶的事務不能被其它用戶的事務所干擾,多個并發事務之間數據要相互隔離。
4、持久性(Durability)持久性是指一個事務一旦被提交,它對數據庫中數據的改變就是永久性的,接下來即使數據庫發生故障也不應該對其有任何影響。
四、事務的并發訪問問題(隔離性)
如果不考慮隔離性,事務存在3種并發訪問問題。
1、臟讀:一個事務讀到了另一個事務未提交的數據.
2、不可重復讀:一個事務讀到了另一個事務已經提交(update)的數據。引發另一個事務,在事務中的多次查詢結果不一致。
3、虛讀 /幻讀:一個事務讀到了另一個事務已經提交(insert)的數據。導致另一個事務,在事務中多次查詢的結果不一致。
解決并發性問題—設置隔離級別:
1.read uncommitted 讀未提交:一個事務讀到另一個事務沒有提交的數據。
?? a)存在:3個問題(臟讀、不可重復讀、虛讀)。
?? b)解決:0個問題
2.read committed 讀已提交:一個事務讀到另一個事務已經提交的數據。
?? a)存在:2個問題(不可重復讀、虛讀)。
?? b)解決:1個問題(臟讀)
3.repeatable read:可重復讀:在一個事務中讀到的數據始終保持一致,無論另一個事務是否提交。
?? a)存在:1個問題(虛讀)(MySQL中也同時解決了虛讀和幻讀)
?? b)解決:2個問題(臟讀、不可重復讀)
4.serializable 串行化:同時只能執行一個事務,相當于事務中的單線程。
?? a)存在:0個問題。
?? b)解決:3個問題(臟讀、不可重復讀、虛讀)
1).查看當前的隔離級別:
select @@tx_isolation;
2).設置隔離級別:
set session transaction isolation level 上面的四個隔離級別之一;
3).安全和性能對比
安全性:serializable > repeatable read > read committed > read uncommitted
性能 : serializable < repeatable read < read committed < read uncommitted
4).常見數據庫的默認隔離級別:
MySql:repeatable read
Oracle:read committed
在Spring中,默認的事務隔離級別是數據庫的默認級別,通常是READ COMMITTED。你可以使用@Transactional注解的isolation屬性來指定事務的隔離級別。
三、事務傳播行為(Transaction Propagation)
事務傳播行為用于控制一個事務方法如何與另一個事務方法交互,即當一個事務方法調用另一個事務方法時,應該如何處理事務的傳播。Spring定義了七種不同的事務傳播行為:
1、REQUIRED(默認): 如果當前存在事務,則加入該事務;如果當前沒有事務,則創建一個新的事務。這是最常用的傳播行為。
2、SUPPORTS: 如果當前存在事務,則加入該事務;如果當前沒有事務,則以非事務的方式執行。
3、MANDATORY: 必須在一個已有的事務中執行,否則拋出異常。
4、REQUIRES_NEW: 創建一個新的事務,如果當前存在事務,則將當前事務掛起。
5、NOT_SUPPORTED: 以非事務的方式執行操作,如果當前存在事務,則將當前事務掛起。
6、NEVER: 以非事務的方式執行,如果當前存在事務,則拋出異常。
7、NESTED: 如果當前存在事務,則在嵌套事務內執行。嵌套事務是外部事務的一部分,但是有自己的保存點。它可以獨立地提交或回滾。
事務傳播行為(Transaction Propagation) 和 隔離級別(Isolation Level)是事務管理中兩個重要的概念,它們分別用于控制事務的行為和數據的可見性。