Spring Boot 事務的使用

vjgs5006 8年前發布 | 70K 次閱讀 Spring JEE框架

來自: http://blog.csdn.net/catoop/article/details/50595702


Spring Boot 使用事務非常簡單,首先使用注解 @EnableTransactionManagement 開啟事務支持后,然后在訪問數據庫的Service方法上添加注解 @Transactional 便可。

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

你可以在啟動類中添加如下方法,Debug測試,就能知道自動注入的是 PlatformTransactionManager 接口的哪個實現類。

@EnableTransactionManagement // 啟注解事務管理,等同于xml配置方式的 <tx:annotation-driven />
@SpringBootApplication
public class ProfiledemoApplication {

@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);
}

}</pre>

這些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);
}

}</pre>

在Spring容器中,我們手工注解@Bean 將被優先加載,框架不會重新實例化其他的 PlatformTransactionManager 實現類。

然后在Service中,被 @Transactional 注解的方法,將支持事務。如果注解在類上,則整個類的所有方法都默認支持事務。

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

@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);
}

}</pre>

@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()<<<<<<<<");
}

}</pre>

注:
如果Spring容器中存在多個 PlatformTransactionManager 實例,并且沒有實現接口 TransactionManagementConfigurer 指定默認值,在我們在方法上使用注解 @Transactional 的時候,就必須要用value指定,如果不指定,則會拋出異常。

對于系統需要提供默認事務管理的情況下,實現接口 TransactionManagementConfigurer 指定。

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

</div>

 本文由用戶 vjgs5006 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!