事務簡介
- 事務:一系列操作,使數據庫從一個狀態轉換到另一個狀態,且保證要麼全部成功要麼全部失敗。
- 事務滿足 ACID 原則:
- 原子性:不可分割,要麼全部成功,要麼全部失敗
- 一致性:從一個狀態到另一個狀態
- 隔離性:正確提交前,可能到結果不應顯示給其他事務
- 持久性:提交後,永久保存在數據庫中
Java事務
- 在Java編寫的程序實現ACID操作,把數據庫的增刪改查的事務操作轉移到Java代碼中控制。
- Java事務機制和原理就是確保數據庫操作的ACID特性。
Java事務實現模式
- Java事務類型
- JDBC事務:侷限在一個數據庫連接內。
- JTA(Java Transaction API)事務:與實現無關的,與協議無關的API。可跨多個數據庫或多個DAO。
- 容器事務:應用服務器提供的。
Spring事務核心接口
Spring事務屬性定義
事務屬性
- 傳播行爲
int getPropagationBehavior()
- 隔離規則
int getIsolationLevel()
- 回滾規則
- 事務超時
int getTimeout()
- 是否只讀?
boolean isReadOnly()
隔離規則
- 髒讀:事務沒提交,被提前讀取。
- 不可重複讀:兩次讀取數據不一致。
- 幻讀:事務不是獨立執行時發生的一種非預期現象。比如第一個事務修改表中數據全部爲男的,第二個事務插入了一個女的,第一個事務再次讀取全表發現怎麼還有個女的。
事務隔離級別:定義了一個事務可能受其他併發事務影響的程度。
- ISOLATION_DEFAULT
- ISOLATION_READ_UNCOMMITTED 髒讀,不可重複度,幻讀
- ISOLATION_READ_COMMITTED 避免髒讀,仍然會有不可重複讀,幻讀
- ISOLATION_REPEATABLE_READ 避免髒讀,不可重複讀,任然會有幻讀
- ISOLATION_SERIALIZABLE 全部避免,也是最慢的
事務傳播行爲
- 當事務方法被另一個事務方法調用時,必須指定事務應該如何傳播;
- spring的7種傳播行爲:
- PROPAGATION_RREQUIRED 當前方法必須運行在事務中。如果不存在事務,則新啓動一個事務
- PROPAGATION_RSUPPORTS 當前方法不需要事務上下文。如果存在事務則在事務中運行
- PROPAGATION_RMANDATORY 當前方法必須運行在事務中。如果不存在事務,則拋出異常
- PROPAGATION_RREQUIRED_NEW 當前方法必須運行在他自己的事務中,一個新事務會被啓動。如果存在當前事務,在該方法執行期間會被掛起。
- PROPAGATION_RNOT_SUPPORTED 該方法不應該運行在事務中。如果存在事務,在該方法運行期間則被掛起。
- PROPAGATION_RNEVER 當前方法不應該運行在事務上下文。如果當前正有一個事務在運行,則會拋異常
- PROPAGATION_RNESTED 如果當前存在一個事務,則該方法會在嵌套事務中運行。嵌套的事務可以獨立於當前事務進行單獨的提交或回滾。如果當前事務不存在,則和PROPAGATION_REQUIRED一樣。
事務是否只讀
- 利用數據庫事務的“只讀”屬性,進行特定優化處理。
- 設置“只讀”,注意數據庫廠商的支持。Oracle的“readOnly”不起作用,MySQL的“readOnly”影響查詢
事務超時
- 事務超時是一個定時器,在特定時間內完成,否則回滾。
- 設計事務的注意點:事務不能運行太長時間,否則佔用太久資源
事務回滾
- 運行期異常纔回滾,而檢查型異常不會回滾
- 自定義回滾策略
- 遇到特定的檢查型異常時像運行期異常一樣回滾。
- 遇到特定的異常不回滾,即使是運行期異常。
事務狀態
- 通過事務管理器獲得TransactionStatus實例
- 控制事務回滾或提交時需要應用對應的事務狀態
編程式事務管理概述
- 事務管理器方式 spring事務管理的三個接口
- 步驟:
- 獲取事務管理器;創建事務屬性對象
- 獲取事務狀態對象;創建JDBC模版對象
- 業務數據操作
- 步驟:
- 模版事務的方式(推薦) JdbcTemplate
- 步驟:
- 獲取模版對象
- 選擇事務結果類型
- 業務數據操作處理
- 步驟:
- 總結:
- 需要有效的數據源
- 創建編程事務管理對象
- 業務邏輯
聲明式事務管理
- 基於AOP,對方法前後攔截
- 配置類型:tx攔截器;註解方式
- 實現方式:
- tx攔截器 使用XML配置
- 註解方式
事務管理最佳實踐
- 編程式更精確自定義,聲明式更解耦業務
- 小型,業務少,直觀的的用編程式
- 大型,事務操作量,複雜的用聲明式
- 事務管理器類型
- 不同數據源用不同的事務管理器
- 正確選擇PlatformTransactionManager實現類
- 全局事務的選擇JtaTransactionManager
- 不同數據源用不同的事務管理器
參考
- Spring事務管理,https://class.imooc.com/course/577
關於我:
linxinzhe,全棧工程師,目前供職於某世界500強銀行的金融科技部門(人工智能,區塊鏈)。
GitHub:https://github.com/linxinzhe
歡迎留言討論,也歡迎關注我~
我也會關注你的哦!