1. 程式人生 > >淺談spring事務管理的2種方式:程式設計式事務管理和宣告式事務管理;以及@Transactional(rollbackFor=Exception.class)註解用法

淺談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