Spring AOP에 대한 자세한 설명이 필요하다면 [Spring/개념] - Spring AOP (Proxy)를 확인하기 바란다.
이전 포스팅([Spring Boot/DB 설정] - [DBCP] HikariCP)에서 DBCP까지 설정하였다.
다음으로는 AOP를 사용하여 Transaction설정을 하려고 한다.
Transaction이란 여러 작업 들을 하나로 묶은 단위이다. 다시 말해서, 한 번에 수행되어야 할 쿼리의 묶음이다. 한 덩어리의 작업들은 모두 실행되거나 모두 실행되지 않아야 한다.
ACID에서 트랜잭션의 성격을 가장 잘 표현한 것은 원자성(Atomicity)이다.
쉽게 이야기해서 트랜잭션의 여러 가지 작업들 중 하나라도 실패 처리되었다면
앞에서 성공했던 작업들도 모두 원래 상태로 되돌아가야 합니다.
특성 | 설명 |
원자성(Atomicitiy) | 모든 작업이 반영되거나 모두 Rollback되는 특성이다. |
일관성(Consistency) | 트랜잭션이 성공했다면 데이터베이스의 모든 데이터는 일관성을 유지해야 합니다. ex) NUMBER컬럼에 VARCHAR를 넣을 수 없다. |
고립성(Isolation) | 트랜잭션은 독립적으로 처리되며, 처리되는 중간에 외부에서의 간섭은 없어야 합니다. |
지속성(Durability) | 트랜잭션은 독립적으로 처리되면 그 결과는 지속적으로 유지되어야 합니다. |
@Configuration
@MapperScan(basePackages = {"mapper들이 있는 패키지경로"})
public class DBConfiguration {
@Autowired
ApplicationContext applicationContext;
@Bean
@ConfigurationProperties(prefix="spring.datasource.hikari")
public HikariConfig hikariConfig() {
return new HikariConfig();
}
@Bean
public DataSource dataSource() {
DataSource dataSource = new HikariDataSource(hikariConfig());
System.out.println("DataSource connection : " + dataSource.toString());
return dataSource;
}
@Bean
public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource) throws IOException {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(dataSource);
factoryBean.setConfigLocation(applicationContext.getResource("classpath:/mybatis/mybatis-config.xml"));
factoryBean.setMapperLocations(applicationContext.getResources("classpath:/mapper/**/*Mapper.xml"));
return factoryBean;
}
@Bean
public SqlSessionTemplate sqlSession(SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
@Bean
public PlatformTransactionManager transactionManager() {
return new DataSourceTransactionManager(dataSource());
}
}
application.yml 등의 설정은 이전 포스팅([Spring Boot/DB 설정] - [DBCP] HikariCP)을 참고하기 바란다.
PlatformTransactionManager는 Spring에서 제공하는 트랜잭션 매니저이다. PlatformTransactionManager를 Bean으로 등록한다.
@Configuration
public class TransactionAspect {
@Autowired
private PlatformTransactionManager transactionManager;
private static final String AOP_TRANSACTION_EXPRESSION = "execution(* com.cm.service..*Impl.*(..))";
@Bean
public TransactionInterceptor transactionAdvice() {
List<RollbackRuleAttribute> rollbackRules = new ArrayList<RollbackRuleAttribute>();
rollbackRules.add(new RollbackRuleAttribute(Exception.class));
rollbackRules.add(new RollbackRuleAttribute(Error.class));
RuleBasedTransactionAttribute transactionAttribute = new RuleBasedTransactionAttribute();
transactionAttribute.setRollbackRules(rollbackRules);
transactionAttribute.setName("*");
MatchAlwaysTransactionAttributeSource attributeSource = new MatchAlwaysTransactionAttributeSource();
attributeSource.setTransactionAttribute(transactionAttribute);
return new TransactionInterceptor(transactionManager, attributeSource);
}
@Bean
public Advisor transactionAdvisor() {
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
pointcut.setExpression(AOP_TRANSACTION_EXPRESSION);
return new DefaultPointcutAdvisor(pointcut, transactionAdvice());
}
}
@Autowired
private PlatformTransactionManager transactionManager;
DBConfiguration에서 등록한 Bean
@Bean
public TransactionInterceptor transactionAdvice() {
List<RollbackRuleAttribute> rollbackRules = new ArrayList<RollbackRuleAttribute>();
rollbackRules.add(new RollbackRuleAttribute(Exception.class));
rollbackRules.add(new RollbackRuleAttribute(Error.class));
RuleBasedTransactionAttribute transactionAttribute = new RuleBasedTransactionAttribute();
transactionAttribute.setRollbackRules(rollbackRules);
transactionAttribute.setName("*");
MatchAlwaysTransactionAttributeSource attributeSource = new MatchAlwaysTransactionAttributeSource();
attributeSource.setTransactionAttribute(transactionAttribute);
return new TransactionInterceptor(transactionManager, attributeSource);
}
rollbackRules은 트랜잭션의 Rollback을 수행하는 규칙이다.
Exception에는 unChecked Exception, checked Exception이 있기 때문에 최상위 클래스인 Exception을 rollbackRule로 등록하였다.
Exception에 대한 자세한 내용은 checked / UnChecked Exception / @Transactional rollback 참고바란다.
private static final String AOP_TRANSACTION_EXPRESSION = "execution(* com.cm.service..*Impl.*(..))";
@Bean
public Advisor transactionAdvisor() {
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
pointcut.setExpression(AOP_TRANSACTION_EXPRESSION);
return new DefaultPointcutAdvisor(pointcut, transactionAdvice());
}
AOP의 Pointcut을 설정한다.
Pointcut
특정 조건에 의해 필터링된 조인 포인트, 수많은 조인포인트 중에 특정 메소드에서만 AOP를 수행시키기 위해서 사용한다.
사용법 : execution([리턴 타입] [패키지] [클래스] [메소드] [매게 변수])
ex: execution(* com.cm.service..*Impl.*(..))
* | 모든 리턴타입 |
com.cm.service.. | com.cm.service로 시작하는 모든 패키지 |
*Impl | 이름이 Imple로 끝나는 모든 클래스 |
*(..) | 모든 메소드 |
Joinpoint
포인트 컷의 후보, 대상으로 생각하면 된다.
SpringBoot logback 파일적재 (2) | 2021.10.27 |
---|---|
SpringBoot logback / log4jdbc 설정 (4) | 2021.10.19 |
Spring JPA란 (1) | 2021.10.17 |
[DBCP] HikariCP (8) | 2021.10.12 |
[Spring Boot] MySQL - Mybatis JAVA config (2) | 2021.10.10 |
댓글 영역