로깅이나 보안, 트랜잭션 같은 공통 기능 로직들을 분리하는 것
public class Member{
private Connection connection;
public void registerMember(Member member) throws SQLException {
connection.setAutoCommit(false); // (1)
try {
saveMember(member);
connection.commit();
} catch (SQLException e) {
connection.rollback();
}
}
private void saveMember(Member member) throws SQLException {
PreparedStatement ps =
connection.prepareStatement("INSERT INTO member (id, password) VALUES (?, ?)");
ps.setString(1, member.getId());
ps.setString(2, member.getPassword());
ps.executeUpdate();
}
}
위의 회원 관리에 대한 로직을 보면, 데이터베이스 트랜잭션에 관한 예외처리가 되어있다. 데이터베이스의 ACID 중 하나인 Atomicity, 원자성을 지키기 위해 SQLException 에서 rollback 메소드가 사용된다.
이러한 예외처리, connection에 관한 처리 등을 모든 기능마다 구현한다면, 코드가 길어지고 객체 지향 설계에 어긋나게 된다.
따라서 해당 트랜잭션 관리는 @Tranctional 어노테이션을 이용하여 해결할 수 있다.
@Component
@Transactional // <--이곳
public class Member {
private Connection connection;
public void registerMember(Member member) throws SQLException {
saveMember(member);
}
private void saveMember(Member member) throws SQLException {
// TODO..
}
}
이처럼 트랜잭션 관리 같은 어플리케이션 전반에 걸쳐 사용되는 기능은 비즈니스 로직 (registerMember 등) 에서 분리하여 재사용 가능한 모듈로 사용할 수 있게 된다.