전 페이지에서 봤던 서비스 계층 코드들은 트랜잭션을 사용하기 위해서 JDBC 기술에 의존하고 있다. 아래처럼..
/**
 * 트랜잭션 - 파라미터 연동, 풀을 고려한 종료
 */
@Slf4j
@RequiredArgsConstructor
public class MemberServiceV2 {
    private final DataSource dataSource;
    private final MemberRepositoryV2 memberRepository;
    public void accountTransfer(String fromId, String toId, int money) throws SQLException {
        Connection con = dataSource.getConnection();
        try {
            con.setAutoCommit(false);//트랜잭션 시작
            //비즈니스 로직
            bizLogic(con, fromId, toId, money);
            con.commit(); //성공시 커밋
        } catch (Exception e) {
            con.rollback(); //실패시 롤백
            throw new IllegalStateException(e);
        } finally {
            release(con);
        }
    }
구현 기술마다 트랜잭션을 사용하는 방법이 다르다..
JDBC : con.setAutoCommit(false)
JPA : transaction.begin()
위의 코드같은 경우는 예외만 하더라도 구현기술을 바꾸면 열심히 예외 잡아놓은 부분들 싹다 고쳐야 할 것이다!
그렇다면!!! 향후 JDBC에서 JPA 같은 다른 데이터 접근 기술로 변경하면, 서비스 계층의 트랜잭션 관련 코드도 모두 함께 수정해야 한다.
이 문제를 해결하기 위해 스프링은 어떤 해결방법을 썻을까? 슬슬 예상 가지 않냐!!
그렇다… 인터페이스로 추상화를 해놓았고,, 각각 맞는 구현체도 이미 다~ 준비되어있다…!!

Like DataSource
이렇게 되면 클라이언트는 인터페이스에만 의존하고 DI를 사용한다면 OCP 원칙을 잘 지켜진 코드를 만들 수 있을 것이다! 이제 트랜잭션을 사용하는 서비스 코드를 전혀 변경하지 않고, 트랜잭션 기술을 맘껏 변경할 수 있다!
TxManager는 이해 하기 쉬우라고 만든 그림이고, 실제로 스프링은

package org.springframework.transaction;
public interface PlatformTransactionManager extends TransactionManager {
	TransactionStatus getTransaction(@Nullable TransactionDefinition
	definition)
			throws TransactionException;
			
	void commit(TransactionStatus status) throws TransactionException;
	void rollback(TransactionStatus status) throws TransactionException;
	}