SpringBoot AOP 설정 1-2. AOP-Transaction 설정

jeonbang123·2023년 3월 28일
0

springboot

목록 보기
5/14

Transaction Manager, AOP로 설정하기

  1. transactionManager @Bean 등록
  2. transactonAdvice, transactionAdvisor @Bean 등록

TransactionManager @Bean 등록

package com.codesign.base.configure;

import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;

@EnableTransactionManagement
@Configuration
@RequiredArgsConstructor
public class DBConfig {

    /**
     * application.yml 설정으로 자동등록되는 datasource
     */
    private final DataSource datasource;

    @Bean
    public PlatformTransactionManager transactionManager(){
        return new DataSourceTransactionManager(datasource);
    }
}
Annotation
설명
@EnableTransactionManagementSpring의 <tx:*> XML 네임스페이스에서 지원되는 것과 유사한 Spring의 주석 기반 트랜잭션 관리 기능을 활성화합니다. @Configuration 클래스에서 기존의 필수 트랜잭션 관리 또는 사후 대응 트랜잭션 관리를 구성하는 데 사용됩니다
@Configuration클래스가 하나 이상의 @Bean 메서드를 선언하고 Spring 컨테이너에 의해 처리되어 런타임에 해당 Bean에 대한 Bean 정의 및 서비스 요청을 생성할 수 있음을 나타냅니다
@RequiredArgsConstructorlombok 에서 제공하는 annotation, 클래스의 final 이나 @NonNull인 필드값을 파라미터로 받는 생성자를자동으로 만들어 줍니다.
package com.codesign.base.common.aop;

import lombok.RequiredArgsConstructor;
import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.interceptor.MatchAlwaysTransactionAttributeSource;
import org.springframework.transaction.interceptor.RollbackRuleAttribute;
import org.springframework.transaction.interceptor.RuleBasedTransactionAttribute;
import org.springframework.transaction.interceptor.TransactionInterceptor;

import java.util.Collections;
import java.util.List;

@Configuration
@RequiredArgsConstructor
public class TransactionAspect {

    /**
     * datasource가 주입되어있음
     */
    private final PlatformTransactionManager transactionManager;

    private final String EXECUTION ="execution(* com.codesign.base..service..*(..))";


    @Bean
    public TransactionInterceptor transactionAdvice(){
        List<RollbackRuleAttribute> rollbackRules = Collections.singletonList(new RollbackRuleAttribute(Exception.class));

        RuleBasedTransactionAttribute transactionAttribute = new RuleBasedTransactionAttribute();
        transactionAttribute.setRollbackRules(rollbackRules);
        transactionAttribute.setName("*");

        MatchAlwaysTransactionAttributeSource attributeSource = new MatchAlwaysTransactionAttributeSource();
        attributeSource.setTransactionAttribute(transactionAttribute);

        TransactionInterceptor interceptor = new TransactionInterceptor();
        interceptor.setTransactionManager(transactionManager);
        interceptor.setTransactionAttributeSource(attributeSource);

        return interceptor;

    }

    @Bean
    public Advisor transactionAdvisor(){
        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
        pointcut.setExpression(EXECUTION);

        return new DefaultPointcutAdvisor(pointcut, transactionAdvice());
    }
}
@Bean
설명
transactionAdvice()rollbackRules - 트랜잭션에서 롤백을 수행하는 규칙(Rule)입니다. RollbackRuleAttribute 생성자의 인자로 Exception 클래스를 지정하였는데요, 자바에서 모든 예외는 Exception 클래스를 상속받기 때문에어떠한 예외가 발생하던 무조건 롤백이 수행됩니다.
setName() - 트랜잭션의 이름을 설정합니다. 트랜잭션 모니터에서 트랜잭션의 이름으로 확인이 가능합니다.
transactionAdvisor()pointcut - AOP의 포인트컷(pointcut)을 설정합니다. EXPRESSION에 지정한 ServiceImpl 클래스의 모든 메서드를 대상으로 설정합니다.

테스트

    @Override
    public int addMember(Map<String, Object> param) throws Exception {

        MemberVo member = new MemberVo();
        member.setMemId("test");
        member.setMemName("test");
        member.setMemPassword("test123!!");

        int result = memberMapper.addMember(member);
        if(result > 0){
            throw new Exception("등록성공 하지만 롤백할꺼지롱");
        }

        return memberMapper.addMember(member);
    }

등록하지만 throw new Exception("등록성공 하지만 롤백할꺼지롱");에서 Exception발생되면서 rollback 시킴!

참고 https://congsong.tistory.com/25

profile
Design Awesome Style Code

0개의 댓글