일하다가 Spring이 제공하는 JdbcTemplate 을 그냥 main 메소드에서 빠르게 돌려야 될 일이 생겼다. 아무래도 standalone으로 MyBatis 같은 걸 돌리려면 좀 번잡해서 JdbcTemplate을 사용했다.
참고로 우리 프로젝트에서는 테스트 프레임워크(= Junit
)를 안 쓴다 😂...
그래서 간단하게 트랜잭션이 적용된 @Test
메소드를 돌리면 좋겠지만,
그러지 못하니 무식하게라도 main 메소드에서 실행한다.
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을 해준다.
만약에 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);
}
}
혹시라도 JdbcTemplate SQL 로그를 보고 싶다면 이 글을 참조하길 바란다.