Spring 中使用事務,以及它的底層原理

spring中幾種事務的實現方式?

1.編程式事務管理對基於 POJO 的應用來講是惟一選擇。咱們須要在代碼中調用beginTransaction()、commit()、rollback()等事務管理相關的方法,這就是編程式事務管理。(已經不用了)html

2.基於 TransactionProxyFactoryBean的聲明式事務管理
3.基於 @Transactional 的聲明式事務管理
4.基於Aspectj AOP配置事務,其實是cjlib動態代理
<aop:aspectj-autoproxy proxy-target-class="true" /> 
<!-- 配置事務管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource">
        <ref bean="dataSource" />
    </property>
</bean>

spring boot如何使用事務?

 springBoot 使用事務很是簡單,首先使用註解 @EnableTransactionManagement 開啓事務支持後,而後在訪問數據庫的Service方法上添加註解 @Transactional 即可。java

關於事務管理器,springBoot默認會幫我注入一個事務管理器,可是當咱們添加的持久化依賴比較多,咱們仍是會選擇人爲的指定使用哪一個事務管理器。 咱們能夠人爲建立多個事務管理器,可是在@Transactional裏面須要顯式給定value屬性spring

http://www.javashuo.com/article/p-aprrydaz-bt.html數據庫

@Transactional加在類上面和方法上面有什麼區別?

而後在Service中,被 @Transactional 註解的方法,將支持事務。若是註解在類上,則整個類的全部方法都默認支持事務。編程

若是你在方法上定義的話,方法的@Transactional會覆蓋類上面聲明的事務。segmentfault

spring中的事務傳播行爲:Propagation這個屬性(7種)

REQUIRED:required(Spring默認的傳播機制是這一個)post

1.在外圍方法未開啓事務的狀況下Propagation.REQUIRED修飾的內部方法會新開啓本身的事務,且開啓的事務相互獨立,互不干擾ui

2.外圍方法開啓事務的狀況下Propagation.REQUIRED修飾的內部方法會加入到外圍方法的事務中,全部Propagation.REQUIRED修飾的內部方法和外圍方法均屬於同一事務,只要一個方法回滾,整個事務均回滾。(共爲一個事務)spa

REQUIRES_NEW:requires_new線程

1.在外圍方法未開啓事務的狀況下Propagation.REQUIRES_NEW修飾的內部方法會新開啓本身的事務,且開啓的事務相互獨立,互不干擾。

2.在外圍方法開啓事務的狀況下Propagation.REQUIRES_NEW修飾的內部方法依然會單獨開啓獨立事務,且與外部方法事務也獨立,內部方法之間、內部方法和外部方法事務均相互獨立,互不干擾。(徹底相互獨立)

NESTED:nested

1.在外圍方法未開啓事務的狀況下Propagation.NESTEDPropagation.REQUIRED做用相同,修飾的內部方法都會新開啓本身的事務,且開啓的事務相互獨立,互不干擾。

2.在外圍方法開啓事務的狀況下Propagation.NESTED修飾的內部方法屬於外部事務的子事務,外圍主事務回滾,子事務必定回滾,而內部子事務能夠單獨回滾而不影響外圍主事務和其餘子事務。(外部回滾,內部必定回滾;內部回滾不影響外部)

PROPAGATION_SUPPORT:支持當前事務,若是當前沒有事務,就不以事務方式運行。

PROPAGATION_MANDATORY:必定要在事務中運行,調用此方法必須原先就有一個事務,不然運行時拋異常。

PROPAGATION_NOT_SUPPORTED:以非事務方式執行,若是以前有事務,將以前事務掛起,此方法內無事務執行。

PROPAGATION_NEVER:以非事務方式執行,若是以前有事務就拋異常。

http://www.javashuo.com/article/p-qqonfnlw-bd.html

Spring中事務的底層原理:

仍是藉助AOP中動態代理的思想,藉助方法攔截器(MethodInterceptor),這裏應該是用的cglib代理,在加入事務處理的方法上額外加一些操做。

 

到這裏,大體介紹完Spring是如何進行事務了,其實現原理源自與自定義標籤,而開啓自定義標籤以後會註冊三個關於Advisor的Bean(AnnotationTransactionAttributeSource類型的Bean,TransactionInterceptor類型的Bean,BeanFactoryTransactionAttributeSourceAdvisor類型的Bean),和一個BeanPostProssor,當Spring中有BeanPostProssor時,會在每一個Bean實例化與依賴注入以後執行BeanPostProssorpostProcessAfterInitialization方法,在這個方法中,會對Bean進行驗證是否須要進行代理,若是須要則將上面的Advisor與此Bean一塊兒去交給動態代理工廠作一個代理,返回代理類給IOC容器,若是不須要進行代理直接返回原Bean,達到了事務的效果。Advisor中的advice是事務功能實現的關鍵類,也就是自定義標籤註冊的Bean中叫作TransactionInterceptor的這個類。

TransactionInterceptor中的invoke方法中會執行:

@Nullable
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
                                         final InvocationCallback invocation) throws Throwable {// 先去獲取事務的屬性
    TransactionAttributeSource tas = getTransactionAttributeSource();
    final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
    // 從屬性中獲取事務管理器,這裏承接上一篇文章中自定義標籤那裏,在配置文件中配置一個事務管理器
    // PlatformTransactionManager有不少種,這裏分析經常使用的DataSourceTransactionManager
    final PlatformTransactionManager tm = determineTransactionManager(txAttr);
    // 給pointcut一個名稱
    final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
 
    if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
        // 這裏執行聲明式事務// 建立一個帶有事務信息的對象TransactionInfo,這個對象是能夠獲取事務管理器的,進而經過事務管理器再執行回滾啊,提交啊這些方法
        TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
        Object retVal = null;
        try {// 執行原方法
            retVal = invocation.proceedWithInvocation();
        }
        catch (Throwable ex) {// 若是有異常就走這裏,對異常進行處理
            completeTransactionAfterThrowing(txInfo, ex);
            throw ex;
        }
        finally {
            // 若是Info裏存在舊的Info,將舊的Info放入當前線程表示將當前Info變爲上一個Info
            cleanupTransactionInfo(txInfo);
        }
        // 若是程序沒有發生異常,就會走到這裏,執行提交的操做
        commitTransactionAfterReturning(txInfo);
        return retVal;
    }
 
    else {
        // 這裏執行編程式事務 本文只討論聲明式事務
        // 略....
    }
}

事務底層原理講的很是好:

https://www.javazhiyin.com/24920.html

https://www.javazhiyin.com/24922.html

事務攔截的對象:TransactionInterceptor

 

Spring事務中的關鍵對象:

PlatformTransactionManager 事務管理器

  包含獲取事務,提交事務,回滾事務三個方法

  getTransaction(TransactionDefinition)

  commit(TransactionStatus)

  roollback(TransactionStatus)

TransactionDefiition

  定義事務的類型,事務包含不少屬性,是否可讀,事務隔離級別,事務傳播級別。經過事務的定義,咱們根據定義獲取特定的事務。

TransactionStatus

  表明一個事務運行的狀態,事務管理器經過狀態能夠知道事務的狀態信息,而後進行事務的控制。事務是否完成,是不是新的事務,是否是隻能回滾等。

 

參考:

https://www.jianshu.com/p/ecf55d6f0118

https://zhuanlan.zhihu.com/p/54067384

相關文章
相關標籤/搜索