【一】spring事務管理
(1)spring的事務管理,是基於aop動態代理實現的。對目標物件生成代理物件,加入事務管理的核心攔截器==>org.springframework.transaction.interceptor.TransactionInterceptor。
===>spring事務管理的核心攔截器
===>需要配置的資料項:事務管理機制配置屬性的查詢類transactionAttributeSource,事務管理的核心處理器PlatformTransactionManager(如果能配置就配置,不能配置就從beanFactory中根據介面拿)
(2)實現事務管理需要配置事務管理處理器(事務處理的支援抽象封裝(獲取事務狀態,提交事務,迴歸事務),如下是spring事務管理器的基礎類。
==>org.springframework.transaction.PlatformTransactionManager
==>org.springframework.transaction.support.AbstractPlatformTransactionManager
(3)獲取將要執行的方法的事務策略的配置資訊的查詢器。
==>org.springframework.transaction.interceptor.TransactionAttributeSource
==>org.springframework.transaction.annotation.AnnotationTransactionAttributeSource(基於註解進行事務管理配置的屬性獲取器)
==>該類內部也做屬性配置快取。以要執行的方法的物件Method method,和要執行的bean的Class<?> targetClass組裝成org.springframework.transaction.interceptor.AbstractFallbackTransactionAttributeSource.DefaultCacheKey.該類重寫了equals和hashCode方法。
(4)spring事務管理的配置屬性的實體類
==>org.springframework.transaction.interceptor.TransactionAttribute
==>org.springframework.transaction.interceptor.DefaultTransactionAttribute(spring的預設)
==>org.springframework.transaction.interceptor.RuleBasedTransactionAttribute(基於註解的事務管理配置屬性的類)
==>其實就是,事務的傳播機制,事務回滾策略等配置資訊
(5)spring事務管理的一個FactoryBean
==>org.springframework.transaction.interceptor.TransactionProxyFactoryBean
==>內部初始化TransactionInterceptor,配置項:可以配置事務管理攔截器增強之外的別的攔截器,需要進行事務管理的的target, 進行事務管理的目標的介面proxyInterfaces
==>該類內部會呼叫afterPropertiesSet()方法,對目標target類生成一個代理物件。最終返回給業務使用。
【二】事務管理攔截器的執行過程TransactionInterceptor的invoke(final MethodInvocation invocation)方法
(1)獲取要進行事務管理的業務類的class的類物件
(2)根據類物件class和要執行的方法的method物件,基於事務管理配置屬性查詢器獲取事務機制的屬性TransactionAttribute
(3)根據事務配置機制的屬性獲取事務管理的處理器PlatformTransactionManager
(4)根據類物件class和要執行的方法method物件獲取事務管理,連線點標識joinpointIdentification(類的全路徑+執行方法的名字)
(5)根據事務管理處理器PlatformTransactionManager,事務機制配置屬性TransactionAttribute,事務連線點標識joinpointIdentification獲取當前事務資訊TransactionInfo
(6)繼續執行下一個攔截器或目標業務管理bean的方法
(7)根據(6)的執行結果進行相應的事務操作
(8)如果(6)沒有丟擲異常,則先根據TransactionInfo進行相關資源的清理,然後根據TransactionInfo進行事務提交操作
(9)如果(6)丟擲異常,則根據TransactionInfo進行事務回滾操作
【三】以xml配置方式進行事務管理的初始化原理解析
(1) 以下配置是事務管理機制屬性配置
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="doReweight" propagation="REQUIRES_NEW"/>
<tx:method name="doClear*" propagation="REQUIRES_NEW"/>
<tx:method name="doSend*" propagation="REQUIRES_NEW"/>
<tx:method name="doBatchSave*" propagation="REQUIRES_NEW"/>
<!--hibernate4必須配置為開啟事務 否則 getCurrentSession()獲取不到-->
<tx:method name="get*" propagation="REQUIRED" read-only="true"/>
<tx:method name="count*" propagation="REQUIRED" read-only="true"/>
<tx:method name="find*" propagation="REQUIRED" read-only="true"/>
<tx:method name="list*" propagation="REQUIRED" read-only="true"/>
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<aop:config expose-proxy="true" proxy-target-class="true">
<!-- 只對業務邏輯層實施事務 -->
<aop:pointcut id="txPointcut" expression="execution(* com.mobile.thinks..service..*+.*(..))"/>
<aop:advisor id="txAdvisor" advice-ref="txAdvice" pointcut-ref="txPointcut"/>
</aop:config>
View Code
(2) 在spring的IOC階段是用org.springframework.transaction.config.TxNamespaceHandler進行解析該<tx:advice>配置,呼叫解析器org.springframework.transaction.config.TxAdviceBeanDefinitionParser
==>如果沒有attributes的配置,則預設的配置屬性查詢器為org.springframework.transaction.annotation.AnnotationTransactionAttributeSource
==>如果attributes的配置大於1個。報錯
==>如果attributes的配置等於1個。
>則解析 <tx:method>的配置。併為每一個method的配置形成一個org.springframework.transaction.interceptor.RuleBasedTransactionAttribute的物件。如果有迴歸策略則形成org.springframework.transaction.interceptor.RollbackRuleAttribute配置。將所有的method配置形成ManagedMap<TypedStringValue, RuleBasedTransactionAttribute> transactionAttributeMap集合
>解析完method後,則想IOC注入事務屬性配置查詢器為org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource.將method解析後的transactionAttributeMap的集合賦值給其屬性nameMap
==>想builder解析上下文註冊了兩個屬性transactionAttributeSource(事務管理機制屬性的查詢器),transactionManager(事務管理的處理器)
==>解析tx的配置,最終形成的advisor是org.springframework.transaction.interceptor.TransactionInterceptor.其依賴了剛才解析的事務管理機制屬性查詢器transactionAttributeSource,和事務管理處理器transactionManager
(3)在spring的IOC階段用的是org.springframework.aop.config.AopNamespaceHandler進行解析 <aop:config >該配置。呼叫的解析器為org.springframework.aop.config.ConfigBeanDefinitionParser
==>預設會向IOC容器中註冊bean實力化的前後置處理器org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator(BeanPostProcessor介面實現類)
==>解析<aop:advisor>是向IOC容器中註冊org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor.並建立txAdvice和txPointcut的依賴關係
==>解析<aop:pointcut>是向IOC容器中註冊org.springframework.aop.aspectj.AspectJExpressionPointcut
=====================================================分割線========================================================
*****spring事務管理是基於對資料庫連結的管理。以下所涉及的類,都是對資料庫DataSource的直接管理,從而對資料庫連結Connection的間接管理從而隱式進行資料庫事務管理******
【一】org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy
==>該類對DataSource進行動態代理,但返回的代理物件是Connection.具體的操作見TransactionAwareInvocationHandler的invoke方法。
==>在對資料庫做任何操作的時候,都在invoke方法中。
【二】org.springframework.jdbc.datasource.TransactionAwareInvocationHandler
==>該類屬性targetDataSource引用的是真正的DataSource實現。
==>該類屬性target引用的是由 DataSourceUtils類透過targetDataSource獲取的一個資料庫連結,該連結與當前執行緒進行繫結。
==>在事務管理過程中Connection做的任何操作,都是代理物件進行操作的。都會呼叫該類的invoke方法,透過該方法對當前執行緒的事務管理進行繫結解綁等等操作。
【三】org.springframework.jdbc.datasource.DataSourceUtils
==>該類是從DataSource獲取資料庫連結,並結合Spring的TransactionSynchronizationManager類進行事務管理的相關操作
==>主要有獲取Connection,釋放Connection等相關操作。
【四】org.springframework.transaction.support.TransactionSynchronizationManager
==>對當前執行緒或當前事務的一些操作進行管理的操作類
==>可以在當前事務中註冊一些事件執行。TransactionSynchronization介面的實現類
【五】org.springframework.transaction.support.TransactionSynchronization
==>該類定義一些事務處理過程中的一些事件處理回撥方法。
==>例子:org.activiti.spring.TransactionSynchronizationAdapter
==>org.activiti.spring.SpringTransactionContext
(1)一個小案例,當事務提交後釋出非同步事件進行相應操作。如果事務未提交,回滾。則不釋出該事件
public static void publishEvent(final ApplicationEvent event) {
if (TransactionSynchronizationManager.isActualTransactionActive()) {
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
@Override
public void afterCommit() {
applicationContext.publishEvent(event);
super.afterCommit();
}
});
} else {
applicationContext.publishEvent(event);
}
}
View Code
(2)測試執行緒保管箱,用於說明TransactionSynchronizationManager屬性中不同的執行緒保管箱的宣告,是用於記錄不同執行緒的事務管理的資訊的儲存。各個執行緒的事務資訊是互不干擾和影響的。
import org.springframework.core.NamedThreadLocal;
/**
* 程式碼測試結果:
* 主執行緒的數值==>【我是主執行緒】
* 非主執行緒的數值====>【我是副執行緒】
* 10秒後被喚醒。。。。。。
* 主執行緒第二次獲取===>【我是主執行緒】
*
* @author sxf
*
*/
public class TestThreadLocal {
public static void main(String[] args) {
//在主執行緒宣告一個ThreadLocal的執行緒保管箱,用於管理不同執行緒儲存的不同的數值。看是否會執行緒間干擾
final ThreadLocal<String> named=new NamedThreadLocal<String>("sxf test");
//主執行緒設定數值
named.set("【我是主執行緒】");
//讀取主執行緒存取的數值
System.out.println("主執行緒的數值==>"+named.get());
//啟動一個新的執行緒,也使用主執行緒宣告的執行緒保管箱
Thread aThread=new Thread(){
@Override
public void run() {
//副執行緒設定數值
named.set("【我是副執行緒】");
//讀取副執行緒的儲存的數值
String falg=named.get();
System.out.println("非主執行緒的數值====>"+falg);
}
};
aThread.start();
//主執行緒休眠10妙,待副執行緒執行完畢,再次從ThreadLocal裡讀取數值,看是否被副執行緒覆蓋
try {
Thread.sleep(10000L);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("10秒後被喚醒。。。。。。");
System.out.println("主執行緒第二次獲取===>"+named.get());
}
}
View Code