Mybatis+Springboot事務管理機制

Mybatis+Springboot整體事務管理機制如下圖



由圖上可以清晰地看出來,Mybatis+Springboot的事務管理的核心類是SqlSessionFactoryBean,然後分爲兩大主線:Springboot事務管理一條主線,MyBatis自己管理事務一條主線;然後繼續,Mybatis自己管理事務也分兩條線:Jdbc管理事務一條線,Managed管理事務一條線。

  1. MyBatis使用Springboot的事務管理
    在Springboot初始化SqlSessionFactoryBean的類裏,有段如下代碼
targetConfiguration.setEnvironment(new Environment(this.environment,
    this.transactionFactory == null ? new SpringManagedTransactionFactory() : this.transactionFactory,
        this.dataSource));

也就是說,如果Mybatis自己沒有配置transactionFactory,那麼就直接使用定義Springboot託管事務管理方案。所以,由此也可以得出一個結論,如果想使用Springboot託管Mybatis事務管理,就一定不能配置Mybatis自己的事務管理。
我們再來看SpringManagedTransactionFactory



它直接使用的是SpringManagedTransaction事務,其核心代碼如下



有此可見,其使用DataSourceUtils去獲取Springboot的事務管理配置來管理Mybatis事務配置。
這就是Springboot託管Mybatis的事務的核心業務邏輯。
下面,我們來看看Springboot是如何把自己的事務管理傳遞給Mybatis的。

在我們使用的DataSourceTransactionManager中,有一段如下代碼

    @Override
    protected Object doGetTransaction() {
        DataSourceTransactionObject txObject = new DataSourceTransactionObject();
        txObject.setSavepointAllowed(isNestedTransactionAllowed());
        ConnectionHolder conHolder =
                (ConnectionHolder) TransactionSynchronizationManager.getResource(obtainDataSource());
        txObject.setConnectionHolder(conHolder, false);
        return txObject;
    }

其中,我們看到了

ConnectionHolder conHolder =
                (ConnectionHolder) TransactionSynchronizationManager.getResource(obtainDataSource());

這裏大家可以看下TransactionSynchronizationManager的源代碼,它藉助ThreadLocal把事務定義存儲到緩存中。
我們回頭來看看Mybatis的Springboot事務管理類SpringManagedTransaction的openConnection()方法有下面代碼

this.connection = DataSourceUtils.getConnection(this.dataSource);

接着往下看


    private static Connection fetchConnection(DataSource dataSource) throws SQLException {
        Connection con = dataSource.getConnection();
        if (con == null) {
            throw new IllegalStateException("DataSource returned null from getConnection(): " + dataSource);
        }
        return con;
    }

這裏,如果能從TransactionSynchronizationManager緩存獲取到connection那麼就直接拿來用,如果獲取不到就直接取數據庫管理事務的鏈接。
而由前面的分析可知,在Springboot託管事務情況下,TransactionSynchronizationManager緩存中是有定義好事務管理信息的connection的,此時就是用Springboot的事務定義來管理Mybatis的事務,實現了事務託管。

  1. Mybatis使用自己的事務管理
    在這種情況下,Springboot未啓用事務管理,或者Mabatis配置了自己的事務管理,也就是this.transactionFactory不爲空,而此時我們只需要在配置文件中定義TransactionFactory爲JdbcTransactionFactory或者ManagedTransactionFactory,然後注入到SqlSessionFactoryBean中,即可實現Mybatis使用自己的事務管理機制。
    --End--
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章