JDBC 기술과 JPA 기술은 트랜잭션을 사용하는 코드 자체가 다르다.
JDBC
Connection con = dataSoure.getConnection()
try{
con.setAutoCommit(false);
bizLogic(con, ...);
con.commit();
} catch(Exception e){
con.rollback();
throw new ...
} finally{
relaese(con);
}
JPA
EntityManagerFactory emf = Persistence.createEntityManagerFacotry("jpabook");
EntityManager em = emf.createEntityManager();
EntityTrasaction tx = em.getTransaction();
try{
tx.begin();
login(em);
tx.commit();
}catch (Exception e){
tx.rollback();
}finally{
em.close()
}
emf.cloae();
기술을 변경할 때 많은 수정이 일어나게 되므로 스프링은 PlatformTransactionMangaer
라는 인터페이스로 추상화를 제공한다.
public interface PlatformTransactionManager extends TransactionManager {
TransactionStatus getTransaction(@Nullable TransactionDefinition definition)
throws TransactionException;
void commit(TransactionStatus status) throws TransactionException;
void rollback(TransactionStatus status) throws TransactionException;
}
스프링은 다양한 데이터 접근 기술에 대한 트랜잭션 매니저의 구현체도 제공할 뿐더러 자동으로 스프링 빈에 등록해주기 때문에 트랜잭션 매니저를 선택하고 등락하는 과정도 생략할 수 있다.
선언적 트랜잭션 관리 : @Transactional
프로그래밍 방식 트랜잭션 관리 : 트랜잭션 매니저 또는 트랜잭션 템플릿을 사용해 코드를 직접 사용하는 것
@Transactional 을 사용하게 되면 앞에 트랜잭션 프록시 역할을 하는 객체를 만든다.
(트랜잭션 매니저 사용)
//트랜잭션 시작
TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
try {
//비즈니스 로직
bizLogic(fromId, toId, money); transactionManager.commit(status); //성공시 커밋
} catch (Exception e) { transactionManager.rollback(status); //실패시 롤백
throw new IllegalStateException(e);
}
트랜잭션은 setAutoCommit(false)한 후 트랜잭션 동기화 매니저에 커넥션을 보관한 이후에 시작된다.
-> 스프링 트랜잭션 AOP는 @Transactional 을 인식해 트랜잭션을 처리하는 처리하는 프록시를 적용해준다.