天天看點

基于AOP實作整體項目事務控制

@[toc]

事務在項目中的用法

在項目中,我們事務一般使用注解的方式控制,當我們的實作類多的時候,業務都需要事務控制的時候,每個方法加 注解,會發現代碼十分十分備援
基于AOP實作整體項目事務控制

我們可以利用Spring 生态下的 AOP實作事務的統一控制

下面我們就介紹下基于AOP事務統一控制(以springboot項目為例)

  1. 引入 需要的pom 檔案
<!-- aop依賴 -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>${aspectj.version}</version>
        </dependency>


        <aspectj.version>1.8.9</aspectj.version>           
  1. 建立 TransactionManagerConfig 類
// 使用Aspect 注解與  Configuration
@Aspect
@Configuration
public class TransactionManagerConfig  {
    private final static Logger logger = LoggerFactory.getLogger(TransactionManagerConfig.class);
    private static final int AOP_TIME_OUT = 50000;
    private static final String AOP_POINTCUT_EXPRESSION = "execution(* com.yxl.demo.impl.*Impl.*(..)))";

    @Autowired
    private PlatformTransactionManager transactionManager;

    @Bean
    public TransactionInterceptor txAdvice(){
        //new NameMatchTransactionAttributeSource 事務屬性
        NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource();

        /** 隻讀事務,不做更新操作 */
        RuleBasedTransactionAttribute readOnlyTx = new RuleBasedTransactionAttribute();
        readOnlyTx.setReadOnly(true);
        readOnlyTx.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);

        /** 目前存在事務就使用目前事務,目前不存在事務就建立一個新的事務 */
        RuleBasedTransactionAttribute requiredTx = new RuleBasedTransactionAttribute();

        /** 什麼異常需要復原 */
        requiredTx.setRollbackRules(Collections.singletonList(new RollbackRuleAttribute(Exception.class)));
        requiredTx.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        requiredTx.setTimeout(AOP_TIME_OUT);

        Map<String, TransactionAttribute> methodMap = new HashMap<>();
        // 復原事務的方法,增删改
        methodMap.put("add*", requiredTx);
        methodMap.put("save*", requiredTx);
        methodMap.put("update*", requiredTx);
        methodMap.put("modify*", requiredTx);
        methodMap.put("edit*", requiredTx);
        methodMap.put("insert*", requiredTx);
        methodMap.put("delete*", requiredTx);
        methodMap.put("remove*", requiredTx);

        /** 其他方法無事務,隻讀 */
        methodMap.put("*", readOnlyTx);
        source.setNameMap(methodMap);

        TransactionInterceptor txAdvice = new TransactionInterceptor(transactionManager, source);
        return txAdvice;
    }

    @Bean(name = "txAdviceAdvisor")
    public Advisor txAdviceAdvisor() {
        logger.info("===============================建立txAdviceAdvisor===================================");
        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
        pointcut.setExpression(AOP_POINTCUT_EXPRESSION);
        return new DefaultPointcutAdvisor(pointcut, txAdvice());

    }

}           

他會掃描 com.yxl.demo.impl.Impl.(..) 包下的所有方法的字首

這時候我們可以 用 delete方法寫個空指針測試下