spring事務管理(一) 隔離級別、傳播行為
阿新 • • 發佈:2018-12-20
1.事務的定義
事務是指多個操作單元組成的合集,多個單元操作是整體不可分割的,要麼都操作不成功,要麼都成功。其必須遵循四個原則(ACID)。
- 原子性(Atomicity):即事務是不可分割的最小工作單元,事務內的操作要麼全做,要麼全不做;
- 一致性(Consistency):在事務執行前資料庫的資料處於正確的狀態,而事務執行完成後資料庫的資料還是應該處於正確的狀態,即資料完整性約束沒有被破壞;如銀行轉帳,A轉帳給B,必須保證A的錢一定轉給B,一定不會出現A的錢轉了但B沒收到,否則資料庫的資料就處於不一致(不正確)的狀態。
- 隔離性(Isolation):併發事務執行之間互不影響,在一個事務內部的操作對其他事務是不產生影響,這需要事務隔離級別來指定隔離性;
- 永續性(Durability):事務一旦執行成功,它對資料庫的資料的改變必須是永久的,不會因比如遇到系統故障或斷電造成資料不一致或丟失。
2.事務的型別
1. 資料庫事務分為本地事務和全域性事務
- 本地事務:普通事務,獨立的資料庫,能夠保證操作的ACID特性。
- 全域性事務:分步式事務,涉及兩個或多個數據庫源的事務,即跨越多臺同類或異類資料庫的事務(由每臺數據庫的本地事務組成的),分散式事務旨在保證這些本地事務的所有操作的ACID,使事務可以跨越多臺資料庫;
2. java事務型別分為JDBC事務和JTA事務
3. 按照是否需要程式設計分為程式設計事務和宣告式事務
3.Spring事務隔離級別
spring有五大隔離級別,其在TransactionDefinition介面中定義(列舉類)。看原始碼可知,其默isolation_default(底層資料庫預設級別),其他四個隔離級別跟資料庫隔離級別一致。
- JDBC事務:即為上面說的資料庫事務中的本地事務,通過connection物件控制管理。
- JTA事務:JTA指Java事務API(Java Transaction API),是Java EE資料庫事務規範, JTA只提供了事務管理介面,由應用程式伺服器廠商(如WebSphere Application Server)提供實現,JTA事務比JDBC更強大,支援分散式事務。
- 宣告式事務:通過XML配置或者註解實現。
- 程式設計式事務:通過程式設計程式碼在業務邏輯時需要時自行實現,粒度更小。
- ISOLATION_DEFAULT:用底層資料庫的預設隔離級別,資料庫管理員設定什麼就是什麼
- ISOLATION_READ_UNCOMMITTED: 幻想讀、不可重複讀和髒讀都允許。
- ISOLATION_READ_COMMITTED 允許幻想讀、不可重複讀,不允許髒讀
- ISOLATION_REPEATABLE_READ(可重複讀) 允許幻想讀,不允許不可重複讀和髒讀
- ISOLATION_SERIALIZABLE(序列化)幻想讀、不可重複讀和髒讀都不允許;
資料庫隔離級別越高,執行代價越高,併發執行能力越差,因此在實際專案開發使用時要綜合考慮,為了考慮併發效能一般使用提交讀隔離級別,它能避免丟失更新和髒讀,儘管不可重複讀和幻讀不能避免,但可以在可能出現的場合使用悲觀鎖或樂觀鎖來解決這些問題。
4.傳播行為
有七大傳播行為,也是在TransactionDefinition介面中定義。
- PROPAGATION_REQUIRED:預設值,如果存在一個事務,支援當前事務,如當前沒有事務,則新建一個;
- PROPAGATION_REQUIRES_NEW:始終新建一個事務,如當前原來有事務,則把原事務掛起;
- PROPAGATION_MANDATORY:支援當前事務,如當前沒有事務,則丟擲異常(強制一定要在一個已經存在的事務中執行,業務方法不可獨自發起自己的事務);
- PROPAGATION_NESTED:如果當前事務存在,則在巢狀事務中執行,如果當前沒有事務,則執行與 PROPAGATION_REQUIRED 類似的操作(注意:當應用到JDBC時,只適用JDBC 3.0以上驅動);
- PROPAGATION_SUPPORTS:支援當前事務,如當前沒有事務,則已非事務性執行;
- PROPAGATION_NOT_SUPPORTED:不支援當前事務,始終已非事務性方式執行,如當前事務存在,掛起該事務;
- PROPAGATION_NEVER:不支援當前事務;如果當前事務存在,則引發異常。
5.Spring事務支援
- DataSourceTransactionManager:org.springframework.jdbc.datasource包下,資料來源事務管理類,提供對單個javax.sql.DataSource資料來源的事務管理,只要用於JDBC,Mybatis框架事務管理。
- HibernateTransactionManager:org.springframework.orm.hibernate3包下,資料來源事務管理類,提供對單個org.hibernate.SessionFactory事務支援,用於整合Hibernate框架時的事務管理;注意:該事務管理器只支援Hibernate3+版本,且Spring3.0+版本只支援Hibernate 3.2+版本;
- JtaTransactionManager:位於org.springframework.transaction.jta包中,提供對分散式事務管理的支援,並將事務管理委託給Java EE應用伺服器,或者自定義一個本地JTA事務管理器,巢狀到應用程式中。
內建事務管理器都繼承了抽象類AbstractPlatformTransactionManager,而AbstractPlatformTransactionManager又繼承了介面PlatformTransactionManager
Spring框架支援事務管理的核心是事務管理器抽象,對於不同的資料訪問框架通過實現策略介面PlatformTransactionManager,從而能支援多鍾資料訪問框架的事務管理;
PlatformTransactionManager介面定義如下:
public interface PlatformTransactionManager {
TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;//返回一個已經啟用的事務或建立一個新的事務(具體由TransactionDefinition引數定義的事務屬性決定),返回的TransactionStatus物件代表了當前事務的狀態,其中該方法丟擲TransactionException(未檢查異常)表示事務由於某種原因失敗。
void commit(TransactionStatus status) throws TransactionException;//用於提交TransactionStatus引數代表的事務。
void rollback(TransactionStatus status) throws TransactionException;//用於回滾TransactionStatus引數代表的事務。
}
TransactionDefinition介面定義如下:
public interface TransactionDefinition {
int getPropagationBehavior(); //返回定義的事務傳播行為
int getIsolationLevel(); //返回事務隔離級別
int getTimeout(); //返回定義的事務超時時間
boolean isReadOnly(); //返回定義的事務是否是隻讀的
String getName(); //返回事務名稱
}
TransactionStatus介面定義如下:
public interface TransactionStatus extends SavepointManager {
boolean isNewTransaction(); //返回當前事務是否是新的事務
boolean hasSavepoint(); //返回當前事務是否有儲存點
void setRollbackOnly(); //設定事務回滾
boolean isRollbackOnly(); //設定當前事務是否應該回滾
void flush(); //用於重新整理底層會話中的修改到資料庫,一般用於重新整理如Hibernate/JPA的會話,可能對如JDBC型別的事務無任何影響;
boolean isCompleted(); //返回事務是否完成
}