ibatis 를 이용하여 sql 을 묶음으로 처리 할 수 있었던 executeBatch() 를 MyBatis 에서는 어떻게 할 수 있을까요?
ibatis 와 유사하게 아래와 같이 진행할 수 있습니다.
@Configuration
@MapperScan(basePackages = "com.mybatis.mapper", sqlSessionTemplateRef = "sqlSessionTemplate")
public class MyBatisConfig {
@Autowired private DataSource dataSource; @Bean(name = "sqlSessionFactoryBean") public SqlSessionFactoryBean sqlSessionFactoryBean() throws Exception { SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); sessionFactory.setDataSource(dataSource); sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml")); return sessionFactory; } @Bean(name = "sqlSessionTemplate") @Primary public SqlSessionTemplate sqlSessionTemplate() throws Exception { return new SqlSessionTemplate(sqlSessionFactoryBean().getObject()); } @Bean(name = "batchSqlSessionTemplate") public SqlSessionTemplate batchSqlSessionTemplate() throws Exception {
return new SqlSessionTemplate(sqlSessionFactoryBean().getObject(), ExecutorType.BATCH); // ExecuteType 을 Batch 로 지정
}
} |
@Override
public int batchExecute(Map<String, Object> params) throws Exception {
...
for (::) {
...
batchSqlSessionTemplate.update(“mapper.updateInfos", params);
…
}
batchSqlSessionTemplate.flushStatements(); ...
}
|
SessionTemplate 을 생성할 때, ExecuteType 을 지정할 수 있으며, 이를 BATCH 타입으로 지정하면 됩니다.
한 번 실행해 봅시다.
“Create a new SqlSession 로그를 확인 할 수 있습니다.
의도 했던 대로라면 동일 SqlSession 으로 묶음 처리를 할 것이라고 예상하였으나, 정상적으로 이뤄지지 않음을 확인할 수 있습니다.
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2adea61c] was not registered for synchronization because synchronization is not active
|
추가적으로 위와 같은 로그도 함께 보입니다.
Transaction이 정상적으로 적용이 되지 않아 발생하는 것으로 Transaction처리가 적용되어야 합니다.
Transaction 설정이 되어 있어야 합니다.
만약 @Transactional 을 적용하고자 하는 경우 2가지 방법으로 진행할 수 있습니다.
1. JavaConfig
@EnableTransactionManagement
2. ApplicationContext
<tx:annotation-driven proxy-target-class=“true”/>
|
묶음처리를 적용하고자 하는 메소드에 @Transactional 옵션을 붙여줍니다.
@Transactional
@Override
public int batchExecute(Map<String, Object> params) throws Exception {
...
for (::) {
...
batchSqlSessionTemplate.update(“mapper.updateInfos", params);
…
}
batchSqlSessionTemplate.flushStatements(); ...
}
|
다시 수행해 보면 아래와 같이 수행할 수 있습니다.
현재 Transaction 에서 SqlSession 을 가져와 묶음 처리가 되며, 마지막에 Transaction commit 시 적용되는 것을 확인할 수 있습니다.
Debug 모드를 이용하여 DB 데이터와 함께 확인해 보면 정상적으로 묶음처리가 됨을 알 수 있습니다.
묶음처리 @Transaction 처리는 어찌보면 당연합니다.
묶음처리란 한 번에 묶음별로 DB에 반영됨을 의미하는데, 이를 Transaction 처리없이 적용하는 것은 의미가 없기 때문입니다.
당연하다고 생각할 수 있지만, 의외로 많이 놓치는 부분입니다.
'Programing > Spring' 카테고리의 다른 글
Spring에서 Json을 파라메터로 넘겼을 때 어떻게 객체로 받을 수 있을까? (0) | 2017.07.21 |
---|---|
Method 주석에 @SQL은 무엇일까? DocletSqlMapClientFactoryBean이란? (0) | 2017.05.29 |
Spring Bean 생성 및 주입 방법 (0) | 2015.06.23 |
@Resource VS @Autowired (0) | 2015.03.12 |
AspectJ를 통한 Spring-AOP 설정 (0) | 2015.03.05 |