● 트랜잭션이란 무엇입니까?
간단히 말해서 트랜잭션은 데이터베이스를 사용하여 수행되는 작업의 최소 단위입니다. 즉, 하나의 트랜잭션이 묶음이며 전체 트랜잭션이 실행되지 않거나 트랜잭션의 일부만 실행되지 않는 것입니다. 여기서 트랜잭션은 하나의 쿼리문으로 반드시 구성되는 것은 아니며, 하나의 트랜잭션으로 여러 개의 쿼리문이 구성될 수 있습니다.
● 거래 특성
1. 원자성
트랜잭션의 모든 작업은 정상적으로 수행되어야 하며, 그렇지 않으면 아무 작업도 수행할 수 없습니다. 트랜잭션 중 오류가 발생하면 지금까지 수행한 모든 작업이 중단되고 데이터베이스를 트랜잭션 작업 이전 상태로 되돌리기 위해 rollback()이 수행됩니다.
2. 일관성
성공적인 트랜잭션 후에도 데이터베이스는 일관된 상태를 유지해야 합니다. 이는 트랜잭션 전후에 일관된 상태가 있어야 함을 의미합니다.
3. 절연
상호 운용 결과는 현재 트랜잭션이 완료될 때까지 다른 트랜잭션에서 액세스할 수 없습니다.
4. 인내
트랜잭션이 성공적으로 완료된 후 데이터베이스에 반영된 실행 결과는 영구적이어야 합니다.
● 커밋 작업 및 롤백 작업
커밋 작업은 트랜잭션이 정상적으로 실행되고 완료되면 작업 결과를 데이터베이스에 반영하여 저장하는 작업입니다. 롤백 작업은 트랜잭션 중 오류가 발생하면 이전에 수행한 모든 작업을 중단하는 작업입니다. 따라서 Spring에서 트랜잭션을 사용할 때 커밋과 롤백을 관리해야 한다.
JDBC의 Connection.setAutoCommit(false)를 사용하여 Spring에서 직접 트랜잭션을 관리할 수 있습니다. 하지만 이 경우 트랜잭션을 코드로 직접 관리하기 때문에 커밋이나 롤백 코드를 놓치기 쉽고 여러 코드가 중복된다. 따라서 Spring에는 트랜잭션 관리 기능을 제공하는 주석이 있습니다.
● @Transactional 주석
@Transaction 어노테이션은 트랜잭션 범위에서 실행하려는 메소드에 첨부할 수 있습니다. 그러면 트랜잭션 단위로 해당 메소드가 실행되고 실행이 끝나면 자동으로 커밋된다.
public class ChangePasswordService {
private MemberDao memberDao;
@Transactional
public void changePassword(String email, String oldPwd, String newPwd) {
Member member = memberDao.selectByEmail(email);
if (member == null)
throw new MemberNotFoundException();
member.changePassword(oldPwd, newPwd);
memberDao.update(member);
}
public void setMemberDao(MemberDao memberDao) {
this.memberDao = memberDao;
}
}
위 코드에서 changePassword() 메서드는 트랜잭션 단위로 실행됩니다. 여기 이 메서드에서 memberDao.selectByEmail 메서드와 업데이트 메서드가 호출됩니다. 이 경우 이 트랜잭션은 이 두 메서드를 포함하는 트랜잭션에 래핑됩니다.
● 플랫폼 트랜잭션 매니저 빈 설정
트랜잭션과 연관될 메서드에 주석을 추가하는 것 외에도 수행해야 할 구성이 하나 더 있습니다. 이는 구성 클래스에 플랫폼 트랜잭션 관리자 빈을 추가하는 것을 의미합니다.
@Configuration
@EnableTransactionManagement
public class AppCtx {
@Bean
public PlatformTransactionManager transactionManager() {
DataSourceTransactionManager tm = new DataSourceTransactionManager();
tm.setDataSource(dataSource());
return tm;
}
}
먼저 구성 클래스에 @EnableTranscationManagement 주석을 추가하고 PlatformTransactionManager 유형의 빈을 추가합니다. 이 Bean 내에서 위의 코드와 같이 데이터베이스 통합을 위한 dataSource를 지정합니다.
@EnableTranscationManagement는 트랜잭션 수준에서 @Transcational을 사용하여 메서드를 실행할 수 있도록 하는 역할입니다. PlatformTransactionManager 빈을 사용하여 트랜잭션을 적용합니다.
● AOP 및 트랜잭션
AOP를 공부하면서 우리는 트랜잭션이 AOP를 사용하여 구현된다는 것을 배웠습니다. 그러나 Spring은 다양하고 편리한 주석 기능을 지원하므로 AOP 코드를 직접 구현할 필요가 없습니다. 그러나 @Transactional은 내부적으로 AOP를 사용하므로 트랜잭션 처리도 프록시를 사용한다는 점을 알아야 합니다.
또한 커밋과 롤백을 수행하는 주체도 프록시이며 다른 설정을 추가하지 않는 한 RuntimeException이 발생할 때 트랜잭션이 롤백됩니다. 그러나 SQLException이 발생하면 롤백이 수행되지 않습니다. 따라서 이 경우에도 롤백하려면 다음 코드와 같이 rollbackFor 속성을 사용해야 합니다.
@Transcational(rollbackFor = SQLException.class)
