Spring Boot實踐--事務管理

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

關於事務管理器,無論是JPA仍是JDBC等都實現自接口 PlatformTransactionManager 若是你添加的是 spring-boot-starter-jdbc 依賴,框架會默認注入 DataSourceTransactionManager 實例。若是你添加的是 spring-boot-starter-data-jpa 依賴,框架會默認注入 JpaTransactionManager 實例。spring

你能夠在啓動類中添加以下方法,Debug測試,就能知道自動注入的是 PlatformTransactionManager 接口的哪一個實現類。數據庫

@EnableTransactionManagement // 啓註解事務管理,等同於xml配置方式的 <tx:annotation-driven />
public class TransactionConfig {

    @Bean
    public Object testBean(PlatformTransactionManager platformTransactionManager){
        System.out.println(">>>>>>>>>>" + platformTransactionManager.getClass().getName());
        return new Object();
    }

}

這些SpringBoot爲咱們自動作了,這些對咱們並不透明,若是你項目作的比較大,添加的持久化依賴比較多,咱們仍是會選擇人爲的指定使用哪一個事務管理器。 
代碼以下:框架

@EnableTransactionManagement
@SpringBootApplication
public class ProfiledemoApplication {

    // 其中 dataSource 框架會自動爲咱們注入
    @Bean
    public PlatformTransactionManager txManager(DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean
    public Object testBean(PlatformTransactionManager platformTransactionManager) {
        System.out.println(">>>>>>>>>>" + platformTransactionManager.getClass().getName());
        return new Object();
    }

    public static void main(String[] args) {
        SpringApplication.run(ProfiledemoApplication.class, args);
    }
}

在Spring容器中,咱們手工註解@Bean 將被優先加載,框架不會從新實例化其餘的 PlatformTransactionManager 實現類。ide

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

對於同一個工程中存在多個事務管理器要怎麼處理,請看下面的實例,具體說明請看代碼中的註釋。測試

@EnableTransactionManagement // 開啓註解事務管理,等同於xml配置文件中的 <tx:annotation-driven />
@SpringBootApplication
public class ProfiledemoApplication implements TransactionManagementConfigurer {

    @Resource(name="txManager2")
    private PlatformTransactionManager txManager2;

    // 建立事務管理器1
    @Bean(name = "txManager1")
    public PlatformTransactionManager txManager(DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    // 建立事務管理器2
    @Bean(name = "txManager2")
    public PlatformTransactionManager txManager2(EntityManagerFactory factory) {
        return new JpaTransactionManager(factory);
    }

    // 實現接口 TransactionManagementConfigurer 方法,其返回值表明在擁有多個事務管理器的狀況下默認使用的事務管理器
    @Override
    public PlatformTransactionManager annotationDrivenTransactionManager() {
        return txManager2;
    }

    public static void main(String[] args) {
        SpringApplication.run(ProfiledemoApplication.class, args);
    }

}
@Component
public class DevSendMessage implements SendMessage {

    // 使用value具體指定使用哪一個事務管理器
    @Transactional(value="txManager1")
    @Override
    public void send() {
        System.out.println(">>>>>>>>Dev Send()<<<<<<<<");
        send2();
    }

    // 在存在多個事務管理器的狀況下,若是使用value具體指定
    // 則默認使用方法 annotationDrivenTransactionManager() 返回的事務管理器
    @Transactional
    public void send2() {
        System.out.println(">>>>>>>>Dev Send2()<<<<<<<<");
    }

}

注: 
若是Spring容器中存在多個 PlatformTransactionManager 實例,而且沒有實現接口 TransactionManagementConfigurer 指定默認值,在咱們在方法上使用註解 @Transactional 的時候,就必需要用value指定,若是不指定,則會拋出異常。.net

對於系統須要提供默認事務管理的狀況下,實現接口 TransactionManagementConfigurer 指定。code

對有的系統,爲了不沒必要要的問題,在業務中必需要明確指定 @Transactional 的 value 值的狀況下。不建議實現接口 TransactionManagementConfigurer,這樣控制檯會明確拋出異常,開發人員就不會忘記主動指定。orm

相關文章
相關標籤/搜索