天天看點

Spring聲明式事務詳解(下)3 代碼實戰

為啥要抽象出PlatformTransactionManager和TransactionStatus?

JavaEE除了提供JDBC事務,還支援分布式事務JTA(Java Transaction API)。分布式事務是指多個資料源(比如多個資料庫,多個消息系統)要在分布式環境下實作事務的時候,

應該怎麼實作。分布式事務實作起來非常複雜,簡單說就是通過一個分布式事務管理器實作兩階段送出,但本身資料庫事務就不快,基于資料庫事務實作的分布式事務就慢得難以忍受,是以使用率不高。

Spring為了同時支援JDBC和JTA兩種事務模型,就抽象出PlatformTransactionManager。

因為我們的代碼隻需要JDBC事務,是以,在AppConfig中,需要再定義一個PlatformTransactionManager對應的Bean,它的實際類型是DataSourceTransactionManager:

@Configuration
@ComponentScan
@PropertySource("jdbc.properties")
public class AppConfig {
    ...
    @Bean
    PlatformTransactionManager createTxManager(@Autowired DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
}      

3 代碼實戰

public OrderService {
    @Autowire PlatformTransactionManager txManager
    void buyTicket(BuyTicketDTO dto) {
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION REQUIRED);
        TransactionStatus status = txManager.getTransaction(def);
        try {
            //執行業務代碼
            txManager.commit(status);
        } catch (Exception e) {
            txManager.rollback(status);
        }
    }   
}         

Transactional标簽方式實作1

public OrderService {
    @Transactonal
    void buyTicket(BuyTicketDTO dto) {
    / save order
    // finish customer pay
    // transfer tickets
    }
}   
      

Transactional标簽方式實作2

public OrderServiceProxy {
    void buyTicket(BuyTicketDTO dto) {
        // get and begin transaction manager from context
        try{
            orderServicelmpl.buyTicket(dto);
            // commit transaction
        } catch (Exceptione) {
            // roolbback transaction
    }
}         

執行原理流程圖

Spring聲明式事務詳解(下)3 代碼實戰

PlatformTransactionManager常見實作

  • DataSourceTransactionManager
  • JpaTransactionManager
  • JmsTransactionManager
  • JtaTransactionManager

但使用聲明式事務經常遇到問題:

資料庫連接配接耗盡

進行中的問題(比如調用接口逾時)