ExecutorType.BATCH 적용, transactionManager 대신 sqlSession.commit(), rollback() 사용

main
icksishu@gmail.com 5 days ago
parent 1622ef03be
commit b68f6395b9

@ -3,6 +3,7 @@ package com.bsmlab.dfx.agent.config.datasource;
import com.bsmlab.dfx.agent.config.AgentConfigDto; import com.bsmlab.dfx.agent.config.AgentConfigDto;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.dbcp2.BasicDataSource; import org.apache.commons.dbcp2.BasicDataSource;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.jdbc.datasource.DataSourceTransactionManager;
@ -70,13 +71,18 @@ public class DynamicDataSourceService {
return this.sqlSessionFactoryMap.get(dataSourceId); return this.sqlSessionFactoryMap.get(dataSourceId);
} }
public SqlSession getSqlSession(String dataSourceId) { /**
* @param dataSourceId
* @param isBatch true
* @return
*/
public SqlSession getSqlSession(String dataSourceId, boolean isBatch) {
SqlSessionFactory sqlSessionFactory = this.sqlSessionFactoryMap.get(dataSourceId); SqlSessionFactory sqlSessionFactory = this.sqlSessionFactoryMap.get(dataSourceId);
SqlSession sqlSession = sqlSessionFactory.openSession(); SqlSession sqlSession = isBatch ? sqlSessionFactory.openSession(ExecutorType.BATCH, false) : sqlSessionFactory.openSession();
Connection connection = sqlSession.getConnection(); Connection connection = sqlSession.getConnection();
if(!this.isConnected(connection)) { if(!this.isConnected(connection)) {
sqlSession.close(); sqlSession.close();
sqlSession = sqlSessionFactory.openSession(); sqlSession = isBatch ? sqlSessionFactory.openSession(ExecutorType.BATCH, false) : sqlSessionFactory.openSession();
log.info("connection is not valid then create new DB connection"); log.info("connection is not valid then create new DB connection");
} }
return sqlSession; return sqlSession;

@ -5,11 +5,7 @@ import com.bsmlab.dfx.agent.config.AgentConfigReader;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSession;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import java.sql.Connection; import java.sql.Connection;
import java.sql.SQLException; import java.sql.SQLException;
@ -27,7 +23,7 @@ public class SqlExecuteService {
public List<Map<String, Object>> select(String dataSourceId, String sqlId, Map<String, Object> parameter) { public List<Map<String, Object>> select(String dataSourceId, String sqlId, Map<String, Object> parameter) {
dynamicRoutingDataSource.setDataSource(dataSourceId); dynamicRoutingDataSource.setDataSource(dataSourceId);
try(SqlSession sqlSession = dynamicDataSourceService.getSqlSession(dataSourceId)) { try(SqlSession sqlSession = dynamicDataSourceService.getSqlSession(dataSourceId, false)) {
return sqlSession.selectList(sqlId, parameter); return sqlSession.selectList(sqlId, parameter);
} }
finally { finally {
@ -37,7 +33,7 @@ public class SqlExecuteService {
public Map<String, Object> insert(String dataSourceId, String sqlId, Map<String, Object> parameter) { public Map<String, Object> insert(String dataSourceId, String sqlId, Map<String, Object> parameter) {
dynamicRoutingDataSource.setDataSource(dataSourceId); dynamicRoutingDataSource.setDataSource(dataSourceId);
try(SqlSession sqlSession = dynamicDataSourceService.getSqlSession(dataSourceId)) { try(SqlSession sqlSession = dynamicDataSourceService.getSqlSession(dataSourceId, false)) {
sqlSession.insert(sqlId, parameter); sqlSession.insert(sqlId, parameter);
return parameter; return parameter;
} }
@ -58,29 +54,31 @@ public class SqlExecuteService {
} }
Map<String, Object> parameter = null; Map<String, Object> parameter = null;
int maximumRowForTransaction = dataSourceConfig == null ? 1000 : dataSourceConfig.getMaximumRowForTransaction(); int maximumRowForTransaction = dataSourceConfig == null ? 1000 : dataSourceConfig.getMaximumRowForTransaction();
DataSourceTransactionManager transactionManager = dynamicDataSourceService.getTransactionManager(dataSourceId);
DefaultTransactionDefinition defaultTransactionDefinition = new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus transactionStatus = transactionManager.getTransaction(defaultTransactionDefinition);
Connection connection = null; Connection connection = null;
if(parameterList.size() > maximumRowForTransaction) { if(parameterList.size() > maximumRowForTransaction) {
try(SqlSession sqlSession = dynamicDataSourceService.getSqlSession(dataSourceId)) { try(SqlSession sqlSession = dynamicDataSourceService.getSqlSession(dataSourceId, false)) {
try {
connection = sqlSession.getConnection(); connection = sqlSession.getConnection();
for(int i = 0; i < parameterList.size(); i++) { for (int i = 0; i < parameterList.size(); i++) {
parameter = parameterList.get(i); parameter = parameterList.get(i);
sqlSession.insert(sqlId, parameter); sqlSession.insert(sqlId, parameter);
resultParameterList.add(parameter); resultParameterList.add(parameter);
if((i + 1) % maximumRowForTransaction == 0) { // maximumRowForTransaction 마다 커밋
sqlSession.flushStatements();
sqlSession.commit();
} }
transactionManager.commit(transactionStatus);
} }
catch(RuntimeException e) { sqlSession.flushStatements(); // 남은 부분 커밋
sqlSession.commit();
} catch (RuntimeException e) {
log.error("dataSourceId: {}, sqlId: {}, parameters: {}", dataSourceId, sqlId, parameter, e); log.error("dataSourceId: {}, sqlId: {}, parameters: {}", dataSourceId, sqlId, parameter, e);
try { try {
transactionManager.rollback(transactionStatus); sqlSession.rollback();
} } catch (RuntimeException ex) {
catch (RuntimeException ex) {
log.warn("Rollback failed", ex); log.warn("Rollback failed", ex);
} }
if(connection != null) { if (connection != null) {
try { try {
connection.close(); connection.close();
} catch (SQLException ex) { } catch (SQLException ex) {
@ -88,26 +86,28 @@ public class SqlExecuteService {
} }
} }
throw e; throw e;
} } finally {
finally {
dynamicRoutingDataSource.clearDataSource(); dynamicRoutingDataSource.clearDataSource();
} }
} }
}
else { else {
try(SqlSession sqlSession = dynamicDataSourceService.getSqlSession(dataSourceId)) { try(SqlSession sqlSession = dynamicDataSourceService.getSqlSession(dataSourceId, false)) {
try {
connection = sqlSession.getConnection(); connection = sqlSession.getConnection();
for(int i = 0; i < parameterList.size(); i++) { for(int i = 0; i < parameterList.size(); i++) {
parameter = parameterList.get(i); parameter = parameterList.get(i);
sqlSession.insert(sqlId, parameter); sqlSession.insert(sqlId, parameter);
resultParameterList.add(parameter); resultParameterList.add(parameter);
} }
transactionManager.commit(transactionStatus); sqlSession.flushStatements();
sqlSession.commit();
return resultParameterList; return resultParameterList;
} }
catch(RuntimeException e) { catch(RuntimeException e) {
log.error("dataSourceId: {}, sqlId: {}, parameters: {}", dataSourceId, sqlId, parameter, e); log.error("dataSourceId: {}, sqlId: {}, parameters: {}", dataSourceId, sqlId, parameter, e);
try { try {
transactionManager.rollback(transactionStatus); sqlSession.rollback();
} }
catch (RuntimeException ex) { catch (RuntimeException ex) {
log.warn("Rollback failed", ex); log.warn("Rollback failed", ex);
@ -126,12 +126,13 @@ public class SqlExecuteService {
dynamicRoutingDataSource.clearDataSource(); dynamicRoutingDataSource.clearDataSource();
} }
} }
}
return resultParameterList; return resultParameterList;
} }
public int update(String dataSourceId, String sqlId, Map<String, Object> parameter) { public int update(String dataSourceId, String sqlId, Map<String, Object> parameter) {
dynamicRoutingDataSource.setDataSource(dataSourceId); dynamicRoutingDataSource.setDataSource(dataSourceId);
try(SqlSession sqlSession = dynamicDataSourceService.getSqlSession(dataSourceId)) { try(SqlSession sqlSession = dynamicDataSourceService.getSqlSession(dataSourceId, false)) {
return sqlSession.update(sqlId, parameter); return sqlSession.update(sqlId, parameter);
} }
finally { finally {
@ -139,17 +140,98 @@ public class SqlExecuteService {
} }
} }
public int update(String dataSourceId, String sqlId, List<Map<String, Object>> parameterList) { public List<Map<String, Object>> update(String dataSourceId, String sqlId, List<Map<String, Object>> parameterList) {
int result = 0; int result = 0;
for(Map<String, Object> parameter : parameterList) { List<Map<String, Object>> resultParameterList = new ArrayList<>();
result += this.update(dataSourceId, sqlId, parameter); dynamicRoutingDataSource.setDataSource(dataSourceId);
List<AgentConfigDto.DataSourceConfig> dataSourceConfigList = agentConfigReader.getAgentConfigDto().getDataSourceConfig();
AgentConfigDto.DataSourceConfig dataSourceConfig = null;
for(AgentConfigDto.DataSourceConfig config : dataSourceConfigList) {
if(dataSourceId.equals(config.getDataSourceId())) {
dataSourceConfig = config;
}
} }
return result; Map<String, Object> parameter = null;
int maximumRowForTransaction = dataSourceConfig == null ? 1000 : dataSourceConfig.getMaximumRowForTransaction();
Connection connection = null;
if(parameterList.size() > maximumRowForTransaction) {
try(SqlSession sqlSession = dynamicDataSourceService.getSqlSession(dataSourceId, false)) {
try {
connection = sqlSession.getConnection();
for (int i = 0; i < parameterList.size(); i++) {
parameter = parameterList.get(i);
result += sqlSession.update(sqlId, parameter);
resultParameterList.add(parameter);
if((i + 1) % maximumRowForTransaction == 0) { // maximumRowForTransaction 마다 커밋
sqlSession.flushStatements();
sqlSession.commit();
}
}
sqlSession.flushStatements(); // 남은 부분 커밋
sqlSession.commit();
} catch (RuntimeException e) {
log.error("dataSourceId: {}, sqlId: {}, parameters: {}", dataSourceId, sqlId, parameter, e);
try {
sqlSession.rollback();
} catch (RuntimeException ex) {
log.warn("Rollback failed", ex);
}
if (connection != null) {
try {
connection.close();
} catch (SQLException ex) {
log.warn("Failed to close connection after error", ex);
}
}
throw e;
} finally {
dynamicRoutingDataSource.clearDataSource();
}
}
}
else {
try(SqlSession sqlSession = dynamicDataSourceService.getSqlSession(dataSourceId, false)) {
try {
connection = sqlSession.getConnection();
for(int i = 0; i < parameterList.size(); i++) {
parameter = parameterList.get(i);
result += sqlSession.update(sqlId, parameter);
resultParameterList.add(parameter);
}
sqlSession.flushStatements();
sqlSession.commit();
}
catch(RuntimeException e) {
log.error("dataSourceId: {}, sqlId: {}, parameters: {}", dataSourceId, sqlId, parameter, e);
try {
sqlSession.rollback();
}
catch (RuntimeException ex) {
log.warn("Rollback failed", ex);
}
if(connection != null) {
try {
connection.close();
}
catch (SQLException ex) {
log.warn("Failed to close connection after error", ex);
}
}
throw e;
}
finally {
dynamicRoutingDataSource.clearDataSource();
}
}
}
log.info("dataSourceId: {}, sqlId: {}, update count: {}", dataSourceId, sqlId, result);
return resultParameterList;
} }
public int delete(String dataSourceId, String sqlId, Map<String, Object> parameter) { public int delete(String dataSourceId, String sqlId, Map<String, Object> parameter) {
dynamicRoutingDataSource.setDataSource(dataSourceId); dynamicRoutingDataSource.setDataSource(dataSourceId);
try(SqlSession sqlSession = dynamicDataSourceService.getSqlSession(dataSourceId)) { try(SqlSession sqlSession = dynamicDataSourceService.getSqlSession(dataSourceId, false)) {
return sqlSession.delete(sqlId, parameter); return sqlSession.delete(sqlId, parameter);
} }
finally { finally {
@ -160,7 +242,7 @@ public class SqlExecuteService {
public void execute(String dataSourceId, String sqlId, Map<String, Object> parameter) { public void execute(String dataSourceId, String sqlId, Map<String, Object> parameter) {
dynamicRoutingDataSource.setDataSource(dataSourceId); dynamicRoutingDataSource.setDataSource(dataSourceId);
try { try {
SqlSession sqlSession = dynamicDataSourceService.getSqlSession(dataSourceId); SqlSession sqlSession = dynamicDataSourceService.getSqlSession(dataSourceId, false);
sqlSession.selectOne(sqlId, parameter); sqlSession.selectOne(sqlId, parameter);
} }
finally { finally {

Loading…
Cancel
Save