트랜잭션 프록시
서비스 Logic() 과 트랜잭션의 분리를 위한 프록시작업
- 트랜잭션 매니저 적용 버전
//트랜잭션 시작
TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
try {
//비즈니스 로직
Logic();
transactionManager.commit(status); //성공시 커밋
}catch (Exception e) {
transactionManager.rollback(status); //실패시 롤백
throw new IllegalStateException(e);
}
- 트랜잭션 프록시 사용 버전
- 서비스와 트랜잭션의 완전한 분리 (서비스계층은 비즈니스로직만 가지고 있을 수 있다)
public class Service{
public void logic(){
Logic(); //실제 비즈니스 로직
}
}
public class Proxy{
private MemberService target;
public void logic(){
TrasactionStatus status = transactionManager.getTransaction(...);
try{
target.logic();
transactionManager.commit(status);
}catch(Exception e){
transactionManager.rollback(status);
throw new IllegalStateException(e);
}
}
}
@Transactional

- 서비스계층에서 트랜잭션이 필요한 곳에 @Transactional 을 사용하면된다
- 위의 프록시를 spring이 이미 구현을 해놓음
- 주의) 리포지토리에서 Connection 직접 close()하지 않도록 조심 (DataSourceUtils.releaseConnection() 사용)
public class Service{
@Transactional
public void func(){
Logic();
}
}
public class Repository{
public Repository(DataSource dataSource) {
this.dataSource = dataSource;
}
private void close(Connection con, Statement stmt, ResultSet rs) {
JdbcUtils.closeResultSet(rs);
JdbcUtils.closeStatement(stmt);
DataSourceUtils.releaseConnection(con, dataSource); // 주의!! 리포지토리에서 connection 닫아버리면 트랜잭션 안됨
}
private Connection getConnection() throws SQLException {
Connection con = DataSourceUtils.getConnection(dataSource);
return con;
}
//... Repository 메서드들 (save(), findById(), delete() ...)
}
'데이터베이스 > JDBC' 카테고리의 다른 글
[JDBC] JDBC 템플릿 (1) | 2024.11.06 |
---|---|
[JDBC] 스프링 예외 변환기 (0) | 2024.11.06 |
[JDBC] 트랜잭션 템플릿 (1) | 2024.11.06 |
[JDBC] 트랜잭션 매니저 (0) | 2024.11.05 |