2018-1-5 by Atlas
+ 簡述
事務是一組邏輯連續的操作,這些操作組合成一個完整的、邏輯的操作。
1. 事務原則
- 原子性(atomicity):
事務是原子操作,組成事務的所有操作的執行結果,要麼都成功,要麼都不成功,不可能部分成功部分不成功。- 一致性(consistency):
事務執行前後,完整性約束沒有被破壞,包括數據完整、邏輯完整。- 隔離性(isolation):
併發的事務執行互不干擾,這些事務併發執行結果和它們先後單獨執行結果一樣。- 持久性(durability):
事務執行完成,事務執行的所有操作結果都會被持久化。
2. 事務隔離
之所以進行事務隔離,是因爲事務併發可能產生問題:
- 髒讀(dirty read):
一個事務執行過程中讀取到了其他事務沒有提交隨後撤銷的中間狀態數據,併發的事務操作後可能對併發訪問的數據造成完整性約束的破壞。- 不可重複讀(non-repeatable read):
一個事務執行過程中讀取到了其他事務已經提交的數據,這個事務多次訪問的數據發生內容更新,可能影響事務邏輯的完整性約束。- 幻讀(phantom read):
一個事務執行過程中讀取到了其他事務已經提交的數據,這個事務多次訪問的數據發生數量更新,可能影響事務邏輯的完整性約束。事務隔離是手段,隔離級別:
- read uncommitted:
存在發生髒讀、不可重複讀、幻讀的情況。- read committed:
解決了髒讀,存在發生不可重複讀、幻讀的情況。- repeatable read:
解決了髒讀、不可重複讀,存在發生幻讀的情況。- serializable:
事務串行,不存在事務併發導致的髒讀、不可重複讀、幻讀問題。
理論上世間萬物相生相剋,不同隔離級別的實現解決問題的程度不同,自然耗費的時間、空間資源也不同,按需選擇。
3. spirng事務定義
public interface TransactionDefinition {
// 事務名稱
String getName();
// 事務傳播行爲
int getPropagationBehavior();
// 事務隔離級別
int getIsolationLevel();
// 事務超時時長
int getTimeout();
// 事務是否只讀
boolean isReadOnly();
}
4.事務狀態
public interface TransactionStatus extends SavepointManager, Flushable {
// 是否新事務
boolean isNewTransaction();
// 是否有安全點
boolean hasSavepoint();
// 標記爲rollback-only
void setRollbackOnly();
// 是否爲rollback-only
boolean isRollbackOnly();
// 是否已經完成
boolean isCompleted();
}
5. spirng事務傳播行爲
方法即行爲,事務傳播行爲即授予方法何種事務行爲。
- PROPAGATION_REQUIRED
執行到當前方法,如果存在事務,則作爲當前事務的操作執行;否則,新建一個事務並執行。- PROPAGATION_SUPPORTS
執行到當前方法,如果存在事務,則作爲當前事務的操作執行;否則,以非事務的方式執行。- PROPAGATION_MANDATORY
執行到當前方法,如果存在事務,則作爲當前事務的操作執行;否則,拋出異常。- PROPAGATION_REQUIRES_NEW
執行到當前方法,如果存在事務,則掛起當前事務,然後新建一個事務並執行,新建的事務和掛起的事務不存在提交等待和失敗回滾依賴,相互獨立;否則,新建一個事務並執行。- PROPAGATION_NOT_SUPPORTED
執行到當前方法,如果存在事務,則掛起當前事務,然後以非事務的方式執行;否則,以非事務的方式執行。- PROPAGATION_NEVER
執行到當前方法,如果存在事務,則拋出異常;否則,以非事務的方式執行。- PROPAGATION_NESTED
類似 PROPAGATION_REQUIRES_NEW ,區別是新建的事務和掛起的事務存在提交等待和失敗回滾依賴,共進退。
6. spirng事務管理
public interface PlatformTransactionManager {
// 接收TransactionDefinition對象 返回TransactionStatus對象
TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;
// 提交
void commit(TransactionStatus status) throws TransactionException;
// 回滾
void rollback(TransactionStatus status) throws TransactionException;
}