아래 내용은 후기 게시판에 적용된 AOP 관련 기능들을 설명한 것이다.
후기 게시판의 CRUD에 대한 쿼리문
Before 영역에 적용됐던 항목은 크게 2가지로
TransactionManager 설정
@Transactional 속성 정의
등이 있는데, 아래에 내용을 조금 더 자세히 적었다.
root-context.xml 빈으로 등록
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
속성 | 적용항목 |
---|---|
isolation level | REPEATABLE READ(Tx이 시작된 이후 변경 무시됨) |
Transaction 경계 | REQUIRED(TX가 진행중이면 참여하고, 없으면 새로운 Tx 시작) |
지정된 예외 | rollbackFor = Exception.class |
timeout | 적용 안함 |
After 영역에 적용됐던 항목은 크게 2가지로
Commit(성공)
Rollback(지정 예외 발생시)
@Transactional(rollbackFor = Exception.class)
public int getCount() throws Exception {
return rvwDao.count();
}
답은 유지보수 쉽고, 코드를 줄일 수 있다는 장점을 가지고 있다.
만약 AOP 설계 없이 직접 다 작성하고, 빈 등록없이 TransactionManager 쓰면 어떻게 될까?
public int write(RvwDto rvwDto) throws Exception {
// TxManager 생성(공통 코드)
PlatformTransactionManager tm = new DataSourceTransactionManager(ds);
TransactionStatus status = tm.getTransaction(new DefaultTransactionDefinition());
try {
rvwDao.insert(rvwDto); // 핵심 기능
tm.commit(status); // 커밋 성공(공통 코드)
return rvwDao.insert(rvwDto);
} catch (Exception ex){ // 커밋 실패(공통 코드)
tm.rollback(status);
}
return 0;
}
AOP 설계했던 코드보다 길어졌고, 오타가 날 확률도 있다. 메서드의 수가 많다면 rvwDao.insert(rvwDto) 를 제외한 공통 코드를 메서드마다 다 적어줘야 한다.
그러면 AOP 설계로 작성하면 어떻게 될까?
@Transactional(rollbackFor = Exception.class)
public int write(RvwDto rvwDto) throws Exception {
return rvwDao.insert(rvwDto);
}
@Transactional(rollbackFor = Exception.class)
한 줄로 코드를 줄이고 훨씬 가독성이 있는 코드로 설계됐다.
또한, 핵심로직만 신경쓰기만 하면 된다는 장점을 가지고 있다.
Transactional 속성 정의 적용 항목들 중, 지정된 예외 그러니까 rollbackFor = Exception.class 사용 이유는 기본적으로 @Transaction은 RuntimeException과 error만 자동 rollback 해주기 때문에 그 이외에 대한 예외가 발생 시 예외 처리해주기 위해 가장 상위단의 예외처리 Exception.class 를 설정했다.
해당 프로젝의 아쉬운 점은
담당 모듈이 후기 게시판만 담당해서 다른 테이블과 같이 Tx 처리되는 부분이 거의 없어서 아쉬웠고, 추후 금융 계산기 미니 프로젝트에서 다른 테이블과의 복수 Tx 처리 중심으로 구성해보려고 한다.