728x90

JDBC를 사용해서 트랜잭션을 직접 다루는 예제고, Spring의 PlatformTransactionManager를 사용해서 명시적으로 트랜잭션을 시작하고 커밋 또는 롤백하는 흐름을 보여줘. 전체적으로 트랜잭션이란 무엇인지, 그리고 SimpleJdbcService, SimpleJdbcCrudTransactionRepository, 그리고 TransactionTests가 어떻게 서로 연결되는지 순서대로 자세하게 설명해보도록 하겠다!


💡 트랜잭션이란?

트랜잭션(Transaction)은 데이터베이스에서 하나의 작업 단위야. 예를 들어 사용자가 은행 계좌에서 돈을 이체할 때,

  1. A 계좌에서 돈을 빼고
  2. B 계좌에 돈을 넣는다

이 두 작업이 모두 성공해야만 데이터베이스에 반영되고, 하나라도 실패하면 둘 다 롤백되어야 해. 이걸 트랜잭션이라고 해.

핵심 개념: ACID

  • Atomicity(원자성): 모두 성공하거나 모두 실패해야 함
  • Consistency(일관성): 무결성 유지
  • Isolation(격리성): 동시에 여러 트랜잭션 실행 시 서로 간섭하면 안 됨
  • Durability(지속성): 커밋된 데이터는 영구 반영됨

 

 


📦 1. SimpleJdbcService

public class SimpleJdbcService {
    private final SimpleCrudRepository repository;
    private final PlatformTransactionManager transactionManager;

    public void logic1(Member saveReq, boolean isRollback) throws Exception{
        TransactionStatus transaction = transactionManager.getTransaction(new DefaultTransactionDefinition());

        try {
            Member saved = repository.save(saveReq); // INSERT
            Optional<Member> memberOptional = repository.findById(saved.getMemberId()); // SELECT
            Member findMember = memberOptional.orElseThrow();

            log.info("findMember.getUsername() = {}", findMember.getUsername());

            if (isRollback) {
                transactionManager.rollback(transaction); // 명시적 롤백
                return;
            }

            transactionManager.commit(transaction); // 커밋

        } catch (Exception e) {
            transactionManager.rollback(transaction); // 예외 발생 시 롤백
        }
    }
}

🔍 설명

  • PlatformTransactionManager: 트랜잭션을 관리하는 Spring의 핵심 인터페이스야.
  • transactionManager.getTransaction(...): 트랜잭션 시작
  • commit(...): 모든 작업이 성공했을 때 반영
  • rollback(...): 문제가 생기면 전부 취소

 

 


🧩 2. SimpleJdbcCrudTransactionRepository

이 클래스는 SimpleCrudRepository 인터페이스를 구현해서 실제 DB 작업을 담당해.

1. save

public Member save(Member member)
  • INSERT 쿼리 실행
  • RETURN_GENERATED_KEYS로 auto-increment된 ID 가져와서 member.setMemberId(...)

 

2. findById

public Optional<Member> findById(Integer id)
  • SELECT 쿼리 실행
  • 결과가 있으면 Optional.of(member) 반환
  • 없으면 Optional.empty()

 

3. update

public void update(Member member)
  • 비밀번호 수정 쿼리

 

4. remove

public void remove(Integer id)
  • 회원 삭제 쿼리

 

💡 여기서 핵심은?

  • DataSourceUtils.getConnection()으로 트랜잭션 연동 가능한 커넥션을 사용함
  • JdbcUtilsDataSourceUtils.releaseConnection()으로 자원 안전하게 반환

 

메서드 설명
save INSERT 후 자동 생성된 ID 반환
findById PK 기반 조회
update 비밀번호 수정
remove 삭제 쿼리 실행 (Hard Delete)

 


🧪 3. TransactionTests

void auto_commit_off() throws Exception

이 테스트는 JDBC에서 직접 트랜잭션을 다루는 코드 예시야.

  • conn.setAutoCommit(false) → 자동 커밋 끔
  • INSERT 쿼리 수행
  • 예외가 발생하면 conn.rollback() 실행
  • 성공하면 conn.commit() 실행

 

 

JDBC로 직접 트랜잭션 다루기

conn.setAutoCommit(false);

try {
    // INSERT
    conn.commit();
} catch (SQLException e) {
    conn.rollback(); // 명시적 롤백
}
  • JDBC에서는 직접 커밋/롤백 해야 함
  • 실무에서는 Spring의 트랜잭션 매니저가 편리함!

 

🔁 전체 흐름 순서 요약

순서 코드 의미
1 conn = getConnection() 커넥션 획득
2 conn.setAutoCommit(false) 트랜잭션 시작 선언
3 stmt.executeUpdate() INSERT 쿼리 수행 (아직 반영 X)
4 conn.commit() 성공 시 → 실제 반영
5 예외 발생 시 conn.rollback() 실패 시 → 트랜잭션 되돌림

 

 

✅ 핵심은?

Spring 없이 수동으로 트랜잭션을 다룰 수도 있지만, 이러면 코드가 복잡하고 중복이 많아져. 그래서 우리는 Spring의 PlatformTransactionManager를 통해 트랜잭션을 더 깔끔하게 관리할 수 있어!

 

 


🔗 정리하면?

구성요소 역할
SimpleJdbcService 트랜잭션을 시작하고 종료하며, DB 로직을 조합
SimpleJdbcCrudTransactionRepository DB에 직접 접근해서 CRUD 수행
TransactionTests JDBC로 트랜잭션을 수동으로 테스트

 

 

 


 

728x90

'프로그래밍 > Spring' 카테고리의 다른 글

Mock이란? - 4월9일  (0) 2025.04.10
MyBatis란?  (0) 2025.04.09
JDBC를 이용한 간단한 CRUD 구현  (0) 2025.04.08
@GeneratedValue란?  (0) 2025.04.07
🌙JPA 매핑 어노테이션 가이드  (0) 2025.04.07