淺談spring事務管理的2種方式:程式設計式事務管理和宣告式事務管理;以及@Transactional(rollbackFor=Exception.class)註解用法
事務的概念,以及特性:
百度百科介紹:
->資料庫事務(Database Transaction) ,是指作為單個邏輯工作單元執行的一系列操作,要麼完全地執行,要麼完全地不執行。 事務處理可以確保除非事務性單元內的所有操作都成功完成,否則不會永久更新面向資料的資源。通過將一組相關操作組合為一個要麼全部成功要麼全部失敗的單元,可以簡化錯誤恢復並使應用程式更加可靠。一個邏輯工作單元要成為事務,必須滿足所謂的 ACID(原子性、一致性、隔離性和永續性)屬性。 事務是資料庫執行中的邏輯工作單位,由DBMS中的事務管理子系統負責事務的處理。
spring 支援程式設計式事務管理以及宣告式事務管理這兩種方式;
1、程式設計式事務:
一種是spring官方推薦使用 TransactionTemplate ,另一種方式就是在PlatformTransactionManager上進行操作;
,
Spring框架進行事務的管理,首先使用TransactionDefinition對事務進行定義。通過PlatformTransactionManager 根據 TransactionDefinition的定義資訊進行事務的管理。在事務管理過程中產生一系列的狀態:儲存到TransactionStatus中
2、宣告式事務:
宣告式事務管理建立在AOP之上的。其本質是對方法前後進行攔截,然後在目標方法開始之前建立或者加入一個事務,在執行完目標方法之後根據執行情況提交或者回滾事務。
一種是基於tx 和 aop名字空間的xml配置檔案,另一種就是基於@Transactional註解;
xml配置可參考https://blog.csdn.net/weixin_42323802/article/details/83870719
@Transactional(rollbackFor=Exception.class)註解用法:
在宣告式註解開發中,@Transactional(rollbackFor=Exception.class)註解作用為,如果類加了這個註解,那麼這個類裡面的方法只要丟擲異常,就會回滾,資料庫裡面的資料也會回滾。
在@Transactional註解中如果不配置rollbackFor屬性,那麼事務只會在RuntimeException的時候才會回滾;
2018.11.14
spring的事務管理器介面 :PlatformTransactionManager
實現類有:
DataSourceTransactionManager SpringJdbc 或者iBatis持久化 使用
HibernateTransactionManager
JpaTransactionManager
JdoTransactionManager
JtaTransactionManager 一個事務跨越多個資源時候必須使用;
事務隔離級別5個:
int ISOLATION_DEFAULT = -1; // 預設級別
int ISOLATION_READ_UNCOMMITTED = 1; // 可以讀未提交
int ISOLATION_READ_COMMITTED = 2; // 可以讀已提交 oracle預設級別
int ISOLATION_REPEATABLE_READ = 4; //是否讀取 其他事務提交修改後的 mysql預設級別
int ISOLATION_SERIALIZABLE = 8; // 是否讀取 其他事務提交新增後的
int TIMEOUT_DEFAULT = -1; 無超時限制
spring事務的傳播行為7個:
int PROPAGATION_REQUIRED = 0; //預設
int PROPAGATION_SUPPORTS = 1; //當前有事務就執行事務,沒有就不執行;
int PROPAGATION_MANDATORY = 2;//使用當前事務,若當前沒有事務 拋異常
int PROPAGATION_REQUIRES_NEW = 3;// 建新事務,若當前有事務,掛起當前事務
int PROPAGATION_NOT_SUPPORTED = 4;//以非事務方式執行,若當前存在事務,掛起當前事務
int PROPAGATION_NEVER = 5;//以非事務方式執行,若當前存在事務,拋異常
int PROPAGATION_NESTED = 6;// 若當前存在事務,巢狀事務執行;由使用者決定,提交還是回滾
資料庫併發引起的一系列讀的問題:
1、髒讀 :read uncommitted
2、不可重複讀:read committed
3、幻讀 :repeatable read
髒讀,事務A讀取事務B未提交的資料,若B回滾,事務A讀取到的資料是無意義的,稱之為髒讀,該問題極為嚴重;
->不可重複讀,事務A執行事務過程中,讀取事務B資料2次,若事務B對資料進行了更新,導致A讀取的結果和第一次不一致;該問題稱之為不可重複讀;
->幻讀,事務A執行過程中,事務B進行了一個更新操作,並提交資料,導致事務A在2次讀取資料結果不一致;
不可重複讀和幻讀的區別:
前者側重於 修改刪除資料,後者側重於資料的新增;
->解決該問題,資料庫新增表級鎖,在事務執行時候,鎖定表;根據鎖定物件不同:分為行級鎖和表級鎖;根據併發事務鎖定的關係上看:分為共享鎖定和獨佔鎖定,共享鎖定會防止獨佔鎖定但允許其他的共享鎖定。而獨佔鎖定既防止共享鎖定也防止其他獨佔鎖定。
由於鎖機制複雜程度較高,所以設定資料庫的隔離級別,資料庫就會自動分析sql語句然後自動選擇合適的鎖;
但是,資料庫隔離級別越高,併發性就越低,一般選擇資料庫預設的即可;
隔離級別 | 髒讀 | 不可重複讀 | 幻讀 | 資料庫預設 |
---|---|---|---|---|
DEFAULT = -1 | ||||
READ_UNCOMMITTED=1 | √ | √ | √ | |
READ_COMMITTED=2 | x | √ | √ | oracle預設的 |
REPEATABLE_READ=4 | x | x | √ | mysql預設的 |
SERIALIZABLE=8 | x | x | x |
參考自 http://www.cnblogs.com/clwydjgs/p/9317849.html
https://blog.csdn.net/starlh35/article/details/76445267