From b68f6395b9afc18644f49e453422909f079660e1 Mon Sep 17 00:00:00 2001 From: "icksishu@gmail.com" Date: Wed, 18 Mar 2026 11:40:32 +0900 Subject: [PATCH] =?UTF-8?q?ExecutorType.BATCH=20=EC=A0=81=EC=9A=A9,=20tran?= =?UTF-8?q?sactionManager=20=EB=8C=80=EC=8B=A0=20sqlSession.commit(),=20ro?= =?UTF-8?q?llback()=20=EC=82=AC=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../datasource/DynamicDataSourceService.java | 12 +- .../config/datasource/SqlExecuteService.java | 210 ++++++++++++------ 2 files changed, 155 insertions(+), 67 deletions(-) diff --git a/src/main/java/com/bsmlab/dfx/agent/config/datasource/DynamicDataSourceService.java b/src/main/java/com/bsmlab/dfx/agent/config/datasource/DynamicDataSourceService.java index 160e9ca..208b36b 100644 --- a/src/main/java/com/bsmlab/dfx/agent/config/datasource/DynamicDataSourceService.java +++ b/src/main/java/com/bsmlab/dfx/agent/config/datasource/DynamicDataSourceService.java @@ -3,6 +3,7 @@ package com.bsmlab.dfx.agent.config.datasource; import com.bsmlab.dfx.agent.config.AgentConfigDto; import lombok.extern.slf4j.Slf4j; import org.apache.commons.dbcp2.BasicDataSource; +import org.apache.ibatis.session.ExecutorType; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.springframework.jdbc.datasource.DataSourceTransactionManager; @@ -70,13 +71,18 @@ public class DynamicDataSourceService { 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); - SqlSession sqlSession = sqlSessionFactory.openSession(); + SqlSession sqlSession = isBatch ? sqlSessionFactory.openSession(ExecutorType.BATCH, false) : sqlSessionFactory.openSession(); Connection connection = sqlSession.getConnection(); if(!this.isConnected(connection)) { 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"); } return sqlSession; diff --git a/src/main/java/com/bsmlab/dfx/agent/config/datasource/SqlExecuteService.java b/src/main/java/com/bsmlab/dfx/agent/config/datasource/SqlExecuteService.java index d73f1f1..44aa117 100644 --- a/src/main/java/com/bsmlab/dfx/agent/config/datasource/SqlExecuteService.java +++ b/src/main/java/com/bsmlab/dfx/agent/config/datasource/SqlExecuteService.java @@ -5,11 +5,7 @@ import com.bsmlab.dfx.agent.config.AgentConfigReader; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.ibatis.session.SqlSession; -import org.springframework.jdbc.datasource.DataSourceTransactionManager; 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.SQLException; @@ -27,7 +23,7 @@ public class SqlExecuteService { public List> select(String dataSourceId, String sqlId, Map parameter) { dynamicRoutingDataSource.setDataSource(dataSourceId); - try(SqlSession sqlSession = dynamicDataSourceService.getSqlSession(dataSourceId)) { + try(SqlSession sqlSession = dynamicDataSourceService.getSqlSession(dataSourceId, false)) { return sqlSession.selectList(sqlId, parameter); } finally { @@ -37,7 +33,7 @@ public class SqlExecuteService { public Map insert(String dataSourceId, String sqlId, Map parameter) { dynamicRoutingDataSource.setDataSource(dataSourceId); - try(SqlSession sqlSession = dynamicDataSourceService.getSqlSession(dataSourceId)) { + try(SqlSession sqlSession = dynamicDataSourceService.getSqlSession(dataSourceId, false)) { sqlSession.insert(sqlId, parameter); return parameter; } @@ -58,72 +54,77 @@ public class SqlExecuteService { } Map parameter = null; 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; if(parameterList.size() > maximumRowForTransaction) { - try(SqlSession sqlSession = dynamicDataSourceService.getSqlSession(dataSourceId)) { - connection = sqlSession.getConnection(); - for(int i = 0; i < parameterList.size(); i++) { - parameter = parameterList.get(i); - sqlSession.insert(sqlId, parameter); - resultParameterList.add(parameter); - } - transactionManager.commit(transactionStatus); - } - catch(RuntimeException e) { - log.error("dataSourceId: {}, sqlId: {}, parameters: {}", dataSourceId, sqlId, parameter, e); + try(SqlSession sqlSession = dynamicDataSourceService.getSqlSession(dataSourceId, false)) { try { - transactionManager.rollback(transactionStatus); - } - catch (RuntimeException ex) { - log.warn("Rollback failed", ex); - } - if(connection != null) { + connection = sqlSession.getConnection(); + for (int i = 0; i < parameterList.size(); i++) { + parameter = parameterList.get(i); + sqlSession.insert(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 { - connection.close(); - } catch (SQLException ex) { - log.warn("Failed to close connection after error", ex); + 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(); } - throw e; - } - finally { - dynamicRoutingDataSource.clearDataSource(); } } else { - try(SqlSession sqlSession = dynamicDataSourceService.getSqlSession(dataSourceId)) { - connection = sqlSession.getConnection(); - for(int i = 0; i < parameterList.size(); i++) { - parameter = parameterList.get(i); - sqlSession.insert(sqlId, parameter); - resultParameterList.add(parameter); - } - transactionManager.commit(transactionStatus); - return resultParameterList; - } - catch(RuntimeException e) { - log.error("dataSourceId: {}, sqlId: {}, parameters: {}", dataSourceId, sqlId, parameter, e); + try(SqlSession sqlSession = dynamicDataSourceService.getSqlSession(dataSourceId, false)) { try { - transactionManager.rollback(transactionStatus); - } - catch (RuntimeException ex) { - log.warn("Rollback failed", ex); + connection = sqlSession.getConnection(); + for(int i = 0; i < parameterList.size(); i++) { + parameter = parameterList.get(i); + sqlSession.insert(sqlId, parameter); + resultParameterList.add(parameter); + } + sqlSession.flushStatements(); + sqlSession.commit(); + return resultParameterList; } - if(connection != null) { + catch(RuntimeException e) { + log.error("dataSourceId: {}, sqlId: {}, parameters: {}", dataSourceId, sqlId, parameter, e); try { - connection.close(); + sqlSession.rollback(); + } + catch (RuntimeException ex) { + log.warn("Rollback failed", ex); } - catch (SQLException ex) { - log.warn("Failed to close connection after error", ex); + if(connection != null) { + try { + connection.close(); + } + catch (SQLException ex) { + log.warn("Failed to close connection after error", ex); + } } + throw e; + } + finally { + dynamicRoutingDataSource.clearDataSource(); } - throw e; - } - finally { - dynamicRoutingDataSource.clearDataSource(); } } return resultParameterList; @@ -131,7 +132,7 @@ public class SqlExecuteService { public int update(String dataSourceId, String sqlId, Map parameter) { dynamicRoutingDataSource.setDataSource(dataSourceId); - try(SqlSession sqlSession = dynamicDataSourceService.getSqlSession(dataSourceId)) { + try(SqlSession sqlSession = dynamicDataSourceService.getSqlSession(dataSourceId, false)) { return sqlSession.update(sqlId, parameter); } finally { @@ -139,17 +140,98 @@ public class SqlExecuteService { } } - public int update(String dataSourceId, String sqlId, List> parameterList) { + public List> update(String dataSourceId, String sqlId, List> parameterList) { int result = 0; - for(Map parameter : parameterList) { - result += this.update(dataSourceId, sqlId, parameter); + List> resultParameterList = new ArrayList<>(); + dynamicRoutingDataSource.setDataSource(dataSourceId); + List dataSourceConfigList = agentConfigReader.getAgentConfigDto().getDataSourceConfig(); + AgentConfigDto.DataSourceConfig dataSourceConfig = null; + for(AgentConfigDto.DataSourceConfig config : dataSourceConfigList) { + if(dataSourceId.equals(config.getDataSourceId())) { + dataSourceConfig = config; + } } - return result; + Map 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 parameter) { dynamicRoutingDataSource.setDataSource(dataSourceId); - try(SqlSession sqlSession = dynamicDataSourceService.getSqlSession(dataSourceId)) { + try(SqlSession sqlSession = dynamicDataSourceService.getSqlSession(dataSourceId, false)) { return sqlSession.delete(sqlId, parameter); } finally { @@ -160,7 +242,7 @@ public class SqlExecuteService { public void execute(String dataSourceId, String sqlId, Map parameter) { dynamicRoutingDataSource.setDataSource(dataSourceId); try { - SqlSession sqlSession = dynamicDataSourceService.getSqlSession(dataSourceId); + SqlSession sqlSession = dynamicDataSourceService.getSqlSession(dataSourceId, false); sqlSession.selectOne(sqlId, parameter); } finally {