1、spring事務(wù)管理器PlatformTransactionManager
1.1、沒有spring事務(wù)管理器時的操作
? ? (1)? jdbc事務(wù)
public void save(User user) throws SQLException{
? ? Connection conn=jdbcDao.getConnection();
? ? conn.setAutoCommit(false);
? ? try {
? ? ? ? PreparedStatement ps=conn.prepareStatement("insert into user(name,age) value(?,?)");
? ? ? ? ps.setString(1,user.getName());
? ? ? ? ps.setInt(2,user.getAge());
? ? ? ? ps.execute();
? ? ? ? conn.commit();
? ? } catch (Exception e) {
? ? ? ? e.printStackTrace();
? ? ? ? conn.rollback();
? ? }finally{
? ? ? ? conn.close();
? ? }
}
? 說明:1、如何使用事務(wù):上圖中獲取連接、將連接的自動提交設(shè)置為setAutoCommit(false)、手動執(zhí)行conn.commit() 或 conn.rollback() 這些屬于事務(wù)代碼,而其他的屬于業(yè)務(wù)代碼;
? ? ? ? ? ? 2、只有業(yè)務(wù)代碼和事務(wù)代碼使用的是同一個Connection時,事務(wù)的回滾或提交才能起作用,所以要實(shí)現(xiàn)【事務(wù)代碼】和【業(yè)務(wù)代碼】的分離就必須保證他們使用的是同一個Connection;
? ? ? ? ? ? 3、誰在執(zhí)行事務(wù):Connection連接并不具有執(zhí)行事務(wù)的功能,他只是把一些命令commit()、rollback()傳遞給數(shù)據(jù)庫,真正使用的是數(shù)據(jù)庫的事務(wù);
? ? ? ? ? ? 4、try-catch塊中的是業(yè)務(wù)代碼,如果這里面有多個業(yè)務(wù)代碼(save.()、update())時沒法保證事務(wù)的一致性,因?yàn)檫@兩個方法使用的是不同的數(shù)據(jù)庫連接Connection;
(2)Hibernate的事務(wù)
public void save(User user){
? ? Session session=hibernateDao.openSession();
? ? Transaction tx=null;
? ? try {
? ? ? ? tx=session.beginTransaction();?
? ? ? ? session.save(user);?
? ? ? ? tx.commit();?
? ? } catch (Exception e) {
? ? ? ? if(tx!=null){
? ? ? ? ? ? tx.rollback();
? ? ? ? }
? ? }finally{
? ? ? ? session.close();
? ? }
}
說明:1、jdbc的Connection肩負(fù)了事務(wù)的開啟、提交和執(zhí)行sql的功能,為了避免這種問題,Hibernate將事務(wù)管理(開始事務(wù)、事務(wù)提交、回滾)和sql執(zhí)行獨(dú)立開來,示例代碼中的Transaction是Hibernate自定義的事務(wù),用于管理事務(wù)的提交、回滾;
? ? ? ? ? 2、Hibernate事務(wù)的原理:Session、Transaction內(nèi)部有一個相同的Connection,這樣保證了業(yè)務(wù)代碼和事務(wù)代碼使用相同的Connection,該Transaction事務(wù)的回滾都是依托內(nèi)部的Connection來完成的;
1.2、spring事務(wù)解決的問題
(1) 基于1.1的分析,實(shí)現(xiàn)事務(wù)功能的方式各不相同,spring針對這種情況進(jìn)行了統(tǒng)一的抽象,抽象為PlatformTransactionManager事務(wù)管理器來進(jìn)行 事務(wù)的提交、回滾等操作,spring事務(wù)功能的總接口為:
PlatformTransactionManager:事務(wù)管理器;
? ? ? TransactionDefinition:事務(wù)的一些基礎(chǔ)信息,如超時時間、隔離級別、傳播屬性等;
? ? ? TransactionStatus:事務(wù)的一些狀態(tài)信息,如是否是一個新的事務(wù)、是否已被標(biāo)記為回滾;
1.3、事務(wù)管理器PlatformTransactionManager
? ? (1)PlatformTransactionManager接口介紹
public interface PlatformTransactionManager {
? ? //根據(jù)事務(wù)定義TransactionDefinition,獲取事務(wù)
? ? TransactionStatus getTransaction(TransactionDefinition var1) throws TransactionException;
? ? //提交事務(wù)
? ? void commit(TransactionStatus var1) throws TransactionException;
? ? //回滾事務(wù)
? ? void rollback(TransactionStatus var1) throws TransactionException;
}
事務(wù)定義包含:事務(wù)的隔離級別、事務(wù)的傳播屬性、超時時間設(shè)置、是否只讀等---事務(wù)的隔離級別是數(shù)據(jù)庫本身的事務(wù)功能,事務(wù)的傳播屬性是spring自己定義的,數(shù)據(jù)庫沒有傳播屬性這種說法;
? ? (2)TransactionDefinition事務(wù)定義
public class DefaultTransactionDefinition implements TransactionDefinition, Serializable {
? ? //事務(wù)的傳播屬性為PROPAGATION_REQUIRED,即當(dāng)前沒有事務(wù)的時候,創(chuàng)建一個,如果有則使用當(dāng)前事務(wù)
? ? private int propagationBehavior = PROPAGATION_REQUIRED;
? ? //事務(wù)的隔離級別采用底層數(shù)據(jù)庫默認(rèn)的隔離級別
? ? private int isolationLevel = ISOLATION_DEFAULT;
? ? //超時時間采用底層數(shù)據(jù)庫默認(rèn)的超時時間
? ? private int timeout = TIMEOUT_DEFAULT;
? ? // 是否只讀為false
? ? private boolean readOnly = false;
? ? //略
}
(3)事務(wù)接口定義TransactionStatus
? //創(chuàng)建一個保存點(diǎn)
Object createSavepoint() throws TransactionException;
// 回滾到保存點(diǎn)
void rollbackToSavepoint(Object var1) throws TransactionException;
//釋放保存點(diǎn)
void releaseSavepoint(Object var1) throws TransactionException;
Spring利用保存點(diǎn)功能實(shí)現(xiàn)了事務(wù)的嵌套,TransactionStatus存儲的是事務(wù)的一些狀態(tài)信息。
? (4)、TransactionStatus的接口實(shí)現(xiàn)為DefaultTransactionStatus
private final Object transaction;
private final boolean newTransaction;
private final boolean newSynchronization;
private final boolean readOnly;
private final boolean debug;
private final Object suspendedResources;
目前jdbc事務(wù)是通過Connection來實(shí)現(xiàn)事務(wù)的,Hibernate是通過他自己定義的Transaction來實(shí)現(xiàn)的,各自的事務(wù)都不同,所以spring使用Object transaction 的形式來表示各自的事務(wù),事務(wù)的回滾、提交都會最終委托給上述的Object transaction 來完成,該Object transaction的選擇可以是:DataSourceTransactionObject、HibernateTransactionObject、JpaTransactionObject;
DataSourceTransactionObject:使用DataSource來獲取連接,要想實(shí)現(xiàn)事務(wù)功能必然要使用Connection,DataSourceTransactionObject中有一個ConnectionHolder,他封裝了一個Connection;
HibernateTransactionObject:使用Hibernate自定義的Transaction來完成事務(wù)操作,含有一個SessionHolder,它里面封裝了一個Session,有了Session就可以創(chuàng)建自定義的Transaction了;
? (5)事務(wù)詳細(xì)分析
? ? ? ? ? 1、通過如下的TransactionStatus getTransaction(@Nullable TransactionDefinition definition) 判斷當(dāng)前事務(wù)是否存在
public interface PlatformTransactionManager{
? TransactionStatus getTransaction(@Nullable TransactionDefinition definition) ;
? void commit(TransactionStatus status);
? void rollback(TransactionStatus status)
}
PlatformTransactionManager的實(shí)現(xiàn)類AbstractPlatformTransactionManager. getTransaction(TransactionDefinition definition)?判斷當(dāng)前事務(wù)是否存在,如果存在則進(jìn)行事務(wù)的傳播性處理,如果不存在則新創(chuàng)建一個事務(wù)。
1.4、DataSourceTransactionObject