1. Global Transactions (Distributed Transactions)
- 여러 트랜잭션 리소스를 하나의 트랜잭션으로 묶어 관리
- 여러 자원간의 데이터 일관성 유지가 목적
JTA (Java Transaction API)
항목 | 설명 |
설명 |
Java에서 전역 트랜잭션을 관리하기 위한 표준 API
|
용도 |
분산 환경에서의 트랜잭션을 통합적으로 관리 (예: 여러 DB, 메시지 큐 등)
|
주요 클래스 |
UserTransaction, TransactionManager 등
|
사용 방식 |
JNDI를 통해 UserTransaction 객체를 주입받아 트랜잭션 제어
|
단점 |
- 복잡성: 예외 처리, 롤백 시나리오 등이 복잡함
- 의존성: JNDI를 통한 객체 주입이 필요 (환경 설정 및 컨테이너 종속성) |
예제) UserTransaction
더보기
public class JTADemo {
public static void main(String[] args) {
UserTransaction userTransaction = null;
try {
// JNDI를 통해 UserTransaction 객체를 주입받아야 함
InitialContext context = new InitialContext();
userTransaction = (UserTransaction) context.lookup("java:comp/UserTransaction");
// 트랜잭션 시작
userTransaction.begin();
// 비즈니스 로직 수행 (예: 여러 데이터베이스에 걸친 작업)
performBusinessLogic();
// 트랜잭션 커밋
userTransaction.commit();
} catch (Exception e) {
// 예외 발생 시 트랜잭션 롤백
try {
if (userTransaction != null) {
userTransaction.rollback();
}
} catch (Exception rollbackEx) {
System.out.println("Rollback failed: " + rollbackEx.getMessage());
}
System.out.println("Transaction failed: " + e.getMessage());
}
}
private static void performBusinessLogic() throws Exception {
// 예외를 던질 수 있는 비즈니스 로직
System.out.println("Executing business logic...");
// 예를 들어, 데이터베이스 작업 중 예외 발생 가능
if (Math.random() > 0.5) {
throw new Exception("Simulated business logic failure");
}
System.out.println("Business logic completed successfully.");
}
}
EJB CMT (Enterprise JavaBeans Container Managed Transations)
항목 | 설명 |
설명 |
트랜잭션 처리를 EJB 컨테이너가 대신 수행하는 방식
|
관리 주체 |
EJB 컨테이너
|
트랜잭션 제어 방법 |
선언적으로 트랜잭션을 정의 (@TransactionAttribute, ejb-jar.xml)
|
사용 대상 |
EJB 컴포넌트 (예: Session Bean)
|
장점 | - 선언적 트랜잭션 관리: 트랜잭션 코드를 작성하지 않고 애너테이션이나 설정만으로 트랜잭션 정의 가능 - 자동 트랜잭션 처리: begin/commit/rollback 등을 컨테이너가 자동 수행 |
단점 | - 의존성: JNDI 및 EJB 컨테이너 환경에 강하게 의존함 - 유연성 부족: 내부적으로 JTA에 강하게 결합됨 |
예시) @TransactionAttribute
더보기
@Stateless
public class CMTExampleBean {
// EJB CMT를 사용하여 선언적으로 트랜잭션을 관리
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void performTransaction() {
// 비즈니스 로직 수행
System.out.println("Performing business logic inside a container-managed transaction.");
// 예외가 발생하면 컨테이너가 자동으로 트랜잭션을 롤백
if (Math.random() > 0.5) {
throw new RuntimeException("Simulated failure");
}
System.out.println("Business logic executed successfully.");
}
}
2. Local Transactions
항목 | 설명 |
설명 |
특정 트랜잭션 자원과 직접 연결된 로컬 트랜잭션 (예: JDBC, JMS 등)
|
관리 주체 |
개발자 (수동 코드로 직접 트랜잭션 제어)
|
지원 범위 |
단일 자원
|
장점 |
- 간단함: 단일 자원에 대해 설정이 간단하여 빠르게 설정할 수 있음
|
단점 |
- 침습성: 트랜잭션 코드(begin(), commit(), rollback())를 직접 작성해야 함
- 확장성 부족: 다중 자원 간 트랜잭션 불가 (JTA 같은 분산 트랜잭션 기술과 연동 불가능) |
예시) JDBC API
더보기
Connection conn = dataSource.getConnection();
try {
conn.setAutoCommit(false); // 트랜잭션 시작
// SQL 실행
stmt1.executeUpdate();
stmt2.executeUpdate();
conn.commit(); // 성공 시 커밋
} catch (Exception e) {
conn.rollback(); // 실패 시 롤백
} finally {
conn.close(); // 연결 종료
}
3. Spring Framework’s Consistent Programming Model
항목 | 설명 |
설명 |
EJB 없이도 독립적인 트랜잭션 관리가 가능하며,
일관된 방식으로 로컬/전역 트랜잭션 처리를 지원함 |
지원 방식 |
선언적 트랜잭션 (@Transactional, XML), 프로그래밍 방식 모두 지원
|
트랜잭션 추상화 |
PlatformTransactionManager를 통해 다양한 트랜잭션 구현체 추상화
|
적용 범위 |
로컬 트랜잭션 + 전역 트랜잭션 모두 처리 가능
|
예시) 설정
더보기
1. 설정클래스 정의
@Configuration
@EnableTransactionManagement
public class AppConfig {
// TransactionMananger 관련 빈 등록하기
}
- @EnableTransactionManagement: 애노테이션 기반 트랜잭션 관리 활성화
2. TransactionManager 설정
@Bean
public PlatformTransactionManager transactionManager() {
return new JtaTransactionManager();
}
항목 | 설명 |
PlatformTransactionManager |
Spring의 트랜잭션 추상화 인터페이스
다양한 트랜잭션 전략을 일관되게 처리 (JDBC, JTA 등) |
JtaTransactionManager |
PlatformTransactionManager의 구현체 중 하나
전역 트랜잭션(JTA) 처리를 지원 |
3. 트랜잭션 속성 설정
@Bean
public TransactionInterceptor transactionInterceptor(PlatformTransactionManager transactionManager) {
Properties transactionAttributes = new Properties();
// 모든 메서드에 대해 REQUIRED 속성을 적용
transactionAttributes.setProperty("*", "PROPAGATION_REQUIRED");
TransactionInterceptor transactionInterceptor = new TransactionInterceptor();
transactionInterceptor.setTransactionManager(transactionManager);
transactionInterceptor.setTransactionAttributes(transactionAttributes);
return transactionInterceptor;
}
항목 | 설명 |
TransactionInterceptor | 트랜잭션 인터셉터를 설정 |
PROPAGATION_REQUIRED | 트랜잭션이 이미 존재하면 참여, 없으면 새 트랜잭션 생성 |
4. 트랜잭션 어드바이스를 자동으로 적용할 프록시 생성기 Bean 지정
@Bean
public BeanNameAutoProxyCreator transactionAutoProxy() {
BeanNameAutoProxyCreator proxyCreator = new BeanNameAutoProxyCreator();
proxyCreator.setInterceptorNames("transactionInterceptor");
proxyCreator.setBeanNames("*Service"); // 예: 서비스 계층에 트랜잭션을 적용
return proxyCreator;
}
- BeanNameAutoProxyCreator: 자동 프록시 생성기. 어드바이스, 포인트컷 설정 가능
예시) 선언적 트랜잭션
더보기
@Service
public class ExampleService {
@Transactional // 이 메서드는 트랜잭션 내에서 실행됨
public void executeInTransaction() {
// 트랜잭션 내에서 실행될 비즈니스 로직
System.out.println("Executing business logic within a transaction.");
}
}
예시) 일관된 프로그래밍 모델
더보기
@Service
public class TransactionalService {
@Autowired
private JdbcTemplate jdbcTemplate; // 로컬 트랜잭션 사용
@Transactional
public void performDatabaseOperation() {
// 로컬 트랜잭션에 대한 작업 수행
jdbcTemplate.update("INSERT INTO my_table (column1) VALUES (?)", "Value1");
// 로컬 트랜잭션과 전역 트랜잭션 간의 코드 차이가 없음
System.out.println("Database operation performed in a transaction.");
}
}
출처