[spring] StandAlone JdbcTemplate with transaction

식빵·2021년 12월 28일
0

Spring Lab

목록 보기
18/33
post-thumbnail

개요

일하다가 Spring이 제공하는 JdbcTemplate 을 그냥 main 메소드에서 빠르게 돌려야 될 일이 생겼다. 아무래도 standalone으로 MyBatis 같은 걸 돌리려면 좀 번잡해서 JdbcTemplate을 사용했다.

참고로 우리 프로젝트에서는 테스트 프레임워크(= Junit)를 안 쓴다 😂...

그래서 간단하게 트랜잭션이 적용된 @Test 메소드를 돌리면 좋겠지만,
그러지 못하니 무식하게라도 main 메소드에서 실행한다.



코드1 : TransactionTemplate 사용


import java.sql.SQLException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.SimpleDriverDataSource;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.support.TransactionTemplate;

public static void main(String[] args) {

    SimpleDriverDataSource dataSource = new SimpleDriverDataSource();
    dataSource.setDriverClass(org.postgresql.Driver.class);
    dataSource.setUrl("jdbc:postgresql://localhost:7932/dailyCode");
    dataSource.setUsername("dailyCode");
    dataSource.setPassword("dailyCode1234");

   // 애플리케이션에서 하나만 만들고 공유해서 사용
   PlatformTransactionManager txManager = new DataSourceTransactionManager(dataSource);

    // 트랜잭션 try-catch 같은 반복되는 코드를 없애주는 TransactionTemplate 생성
    // 설정을 바꾸지 않는 이상 Thread-Safe. 만약 다른 설정이 필요하다면 하나 더 생성
    TransactionTemplate txTemplate = new TransactionTemplate(txManager);

    // 실제 쿼리를 실행하는 jdbcTemplate 생성, Thread-Safe
    JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);

    // 트랜잭션이 적용된 쿼리 수행
    Date execute = txTemplate.execute((state) -> {
        Date result = jdbcTemplate.queryForObject("select now()", Date.class);
        return result;// 반환할게 없다면 그냥 null 처리
        
        // status.setRollbackOnly(); 를 통해서 자기가 원하는 경우에만 롤백 시킬 수도 있다.
    });

    
    System.out.println(execute);
}

txTemplate 내에서 update를 여러번 해도 중간에 에러가 나면 자동으로 rollback 이 된다.
그리고 반대로 정상적으로 내부 로직이 다 돌면 commit을 해준다.



코드2 : PlatformTransactionManager 만 사용

만약에 PlatformTransactionManager 만 이용해서 트랜잭션을 걸려면 아래처럼 한다.

public static void main(String[] args) throws SQLException {

    SimpleDriverDataSource dataSource = new SimpleDriverDataSource();
    dataSource.setDriverClass(org.postgresql.Driver.class);
    dataSource.setUrl("jdbc:postgresql://localhost:7932/dailyCode");
    dataSource.setUsername("dailyCode");
    dataSource.setPassword("dailyCode1234");

    PlatformTransactionManager txManager 
    		= new DataSourceTransactionManager(dataSource);

    // 트랜잭션 속성 정의
    DefaultTransactionDefinition transactionDef = new DefaultTransactionDefinition();
    transactionDef.setTimeout(2); // 초 단위

    // 실제 쿼리를 수행해줄 jdbcTemplate 생성
    JdbcTemplate simpleTemplate = new JdbcTemplate(dataSource);

    TransactionStatus status = txManager.getTransaction(transactionDef);
    try {

        Date result = simpleTemplate.queryForObject("select now()", Date.class);
        System.out.println(result);

        txManager.commit(status);
    } catch (Exception e) {
        e.printStackTrace();
        txManager.rollback(status);
    }
    
}

참고

profile
백엔드를 계속 배우고 있는 개발자입니다 😊

0개의 댓글