feat : 로그인관련 설정 및 다이나믹 트랜젝션 설정, 멀티디비 환경 세팅중

pull/2/head
Kurt92 5 months ago
parent ee46e4f56f
commit 8cf503d16c

@ -1,6 +1,7 @@
package egovframework.config.JPAConf;
import com.querydsl.jpa.impl.JPAQueryFactory;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ -10,11 +11,14 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.persistenceunit.PersistenceUnitManager;
import org.springframework.transaction.PlatformTransactionManager;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import java.util.HashMap;
@Configuration
@EnableJpaRepositories(
@ -39,13 +43,21 @@ public class CpDbConf {
@Bean
@Primary
public LocalContainerEntityManagerFactoryBean cpEntityManagerFactory(EntityManagerFactoryBuilder builder) {
public LocalContainerEntityManagerFactoryBean cpEntityManagerFactory(@Qualifier("cpEntityManagerFactoryBuilder") EntityManagerFactoryBuilder builder) {
return builder
.dataSource(cpDataSource())
.packages("go.kr.project.domain.entity")
.persistenceUnit("cp")
.build();
}
@Bean(name = "cpEntityManagerFactoryBuilder")
public EntityManagerFactoryBuilder entityManagerFactoryBuilder(
JpaVendorAdapter jpaVendorAdapter,
ObjectProvider<PersistenceUnitManager> persistenceUnitManager
) {
return new EntityManagerFactoryBuilder(jpaVendorAdapter, new HashMap<>(), persistenceUnitManager.getIfAvailable());
}
@Bean(name = "cpJpaTransactionManager")
@Primary

@ -1,6 +1,7 @@
package egovframework.config.JPAConf;
import com.querydsl.jpa.impl.JPAQueryFactory;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ -9,11 +10,14 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.persistenceunit.PersistenceUnitManager;
import org.springframework.transaction.PlatformTransactionManager;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import java.util.HashMap;
@Configuration
@EnableJpaRepositories(
@ -35,7 +39,7 @@ public class EpDbConf {
}
@Bean
public LocalContainerEntityManagerFactoryBean epEntityManagerFactory(EntityManagerFactoryBuilder builder) {
public LocalContainerEntityManagerFactoryBean epEntityManagerFactory(@Qualifier("epEntityManagerFactoryBuilder") EntityManagerFactoryBuilder builder) {
return builder
.dataSource(epDataSource())
.packages("go.kr.project.domain.entity")
@ -43,6 +47,14 @@ public class EpDbConf {
.build();
}
@Bean(name = "epEntityManagerFactoryBuilder")
public EntityManagerFactoryBuilder entityManagerFactoryBuilder(
JpaVendorAdapter jpaVendorAdapter,
ObjectProvider<PersistenceUnitManager> persistenceUnitManager
) {
return new EntityManagerFactoryBuilder(jpaVendorAdapter, new HashMap<>(), persistenceUnitManager.getIfAvailable());
}
@Bean(name = "epJpaTransactionManager")
public PlatformTransactionManager epTransactionManager(@Qualifier("epEntityManagerFactory") EntityManagerFactory epEntityManagerFactory) {
return new JpaTransactionManager(epEntityManagerFactory);

@ -1,20 +1,19 @@
package egovframework.config.JPAConf;//package com.worker.framework.JPAConf;
//package egovframework.config.JPAConf;
//
//import com.querydsl.jpa.impl.JPAQueryFactory;
//import jakarta.persistence.EntityManager;
//import jakarta.persistence.PersistenceContext;
//import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.orm.jpa.JpaVendorAdapter;
//import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
//
//@Configuration
//public class JPAConfig {
//
// @PersistenceContext
// private EntityManager em;
//
// @Bean
// public JPAQueryFactory jpaQueryFactory() {
// return new JPAQueryFactory(em);
// public JpaVendorAdapter jpaVendorAdapter() {
// HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
// adapter.setShowSql(false);
// adapter.setGenerateDdl(false);
// adapter.setDatabasePlatform("org.hibernate.dialect.MySQLDialect");
// return adapter;
// }
//}
// 멀티 db 환경으로 conf 수정 수정

@ -1,36 +1,36 @@
package egovframework.config.myBatisConf;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import javax.sql.DataSource;
@Configuration
public class CpMyBatisConf {
@Bean
@Primary
public SqlSessionFactory cpSqlSessionFactory(@Qualifier("cpDataSource") DataSource cpDataSource) throws Exception {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(cpDataSource);
return factoryBean.getObject();
}
@Bean
@Primary
public SqlSessionTemplate cpSqlSessionTemplate(@Qualifier("cpSqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
@Bean(name = "cpMyBatisTransactionManager")
@Primary
public DataSourceTransactionManager cpMyBatisTransactionManager(@Qualifier("cpDataSource") DataSource cpDataSource) {
return new DataSourceTransactionManager(cpDataSource);
}
}
//package egovframework.config.myBatisConf;
//
//import org.apache.ibatis.session.SqlSessionFactory;
//import org.mybatis.spring.SqlSessionFactoryBean;
//import org.mybatis.spring.SqlSessionTemplate;
//import org.springframework.beans.factory.annotation.Qualifier;
//import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.context.annotation.Primary;
//import org.springframework.jdbc.datasource.DataSourceTransactionManager;
//
//import javax.sql.DataSource;
//
//@Configuration
//public class CpMyBatisConf {
//
// @Bean
// @Primary
// public SqlSessionFactory cpSqlSessionFactory(@Qualifier("cpDataSource") DataSource cpDataSource) throws Exception {
// SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
// factoryBean.setDataSource(cpDataSource);
// return factoryBean.getObject();
// }
//
// @Bean
// @Primary
// public SqlSessionTemplate cpSqlSessionTemplate(@Qualifier("cpSqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
// return new SqlSessionTemplate(sqlSessionFactory);
// }
//
// @Bean(name = "cpMyBatisTransactionManager")
// @Primary
// public DataSourceTransactionManager cpMyBatisTransactionManager(@Qualifier("cpDataSource") DataSource cpDataSource) {
// return new DataSourceTransactionManager(cpDataSource);
// }
//}

@ -1,36 +1,33 @@
package egovframework.config.myBatisConf;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import javax.sql.DataSource;
@Configuration
public class EpMyBatisConf {
@Bean
@Primary
public SqlSessionFactory epSqlSessionFactory(@Qualifier("epDataSource") DataSource epDataSource) throws Exception {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(epDataSource);
return factoryBean.getObject();
}
@Bean
@Primary
public SqlSessionTemplate epSqlSessionTemplate(@Qualifier("epSqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
@Bean(name = "epMyBatisTransactionManager")
@Primary
public DataSourceTransactionManager epMyBatisTransactionManager(@Qualifier("epDataSource") DataSource epDataSource) {
return new DataSourceTransactionManager(epDataSource);
}
}
//package egovframework.config.myBatisConf;
//
//import org.apache.ibatis.session.SqlSessionFactory;
//import org.mybatis.spring.SqlSessionFactoryBean;
//import org.mybatis.spring.SqlSessionTemplate;
//import org.springframework.beans.factory.annotation.Qualifier;
//import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.context.annotation.Primary;
//import org.springframework.jdbc.datasource.DataSourceTransactionManager;
//
//import javax.sql.DataSource;
//
//@Configuration
//public class EpMyBatisConf {
//
// @Bean
// public SqlSessionFactory epSqlSessionFactory(@Qualifier("epDataSource") DataSource epDataSource) throws Exception {
// SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
// factoryBean.setDataSource(epDataSource);
// return factoryBean.getObject();
// }
//
// @Bean
// public SqlSessionTemplate epSqlSessionTemplate(@Qualifier("epSqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
// return new SqlSessionTemplate(sqlSessionFactory);
// }
//
// @Bean(name = "epMyBatisTransactionManager")
// public DataSourceTransactionManager epMyBatisTransactionManager(@Qualifier("epDataSource") DataSource epDataSource) {
// return new DataSourceTransactionManager(epDataSource);
// }
//}

@ -1,11 +1,10 @@
package egovframework.dataSourece;
public class DataSourceContextHolder {
private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
public static void set(String dbKey) {
contextHolder.set(dbKey); // ex) "cp" or "ep"
public static void set(String key) {
contextHolder.set(key);
}
public static String get() {
@ -13,7 +12,6 @@ public class DataSourceContextHolder {
}
public static void clear() {
contextHolder.remove(); // 꼭 요청 끝나면 클리어해야 메모리 누수 안 생김
contextHolder.remove();
}
}

@ -0,0 +1,62 @@
//package egovframework.dataSourece;
//
//import org.springframework.aop.Advisor;
//import org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator;
//import org.springframework.aop.support.DefaultPointcutAdvisor;
//import org.springframework.aop.support.annotation.AnnotationMatchingPointcut;
//import org.springframework.beans.factory.annotation.Qualifier;
//import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.transaction.PlatformTransactionManager;
//import org.springframework.transaction.TransactionDefinition;
//import org.springframework.transaction.interceptor.*;
//
//import javax.transaction.Transactional;
//import java.util.Collections;
//import java.util.HashMap;
//import java.util.Map;
//
//@Configuration
//public class DynamicRoutingTransactionConfig {
//
// @Bean
// public TransactionInterceptor dynamicTransactionInterceptor(DynamicTransactionManager dynamicTxManager) {
// NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource();
// RuleBasedTransactionAttribute txAttr = new RuleBasedTransactionAttribute();
// txAttr.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
// txAttr.setRollbackRules(Collections.singletonList(new RollbackRuleAttribute(Exception.class)));
//
// Map<String, TransactionAttribute> txMap = new HashMap<>();
// txMap.put("*", txAttr);
// source.setNameMap(txMap);
//
// return new TransactionInterceptor(dynamicTxManager, source);
// }
//
// @Bean
// public Advisor dynamicTxAdvisor(TransactionInterceptor dynamicTransactionInterceptor) {
// // @DynamicTransactional만 매칭되게 설정
// AnnotationMatchingPointcut pointcut = new AnnotationMatchingPointcut(null, DynamicTransactional.class);
// return new DefaultPointcutAdvisor(pointcut, dynamicTransactionInterceptor);
// }
//
// @Bean
// public DynamicTransactionManager dynamicTxManager(
// @Qualifier("cpJpaTransactionManager") PlatformTransactionManager cp,
// @Qualifier("epJpaTransactionManager") PlatformTransactionManager ep) {
//
// Map<String, PlatformTransactionManager> map = new HashMap<>();
// map.put("cp", cp);
// map.put("ep", ep);
// return new DynamicTransactionManager(map, cp); // default는 cp
// }
//
// @Bean
// public BeanNameAutoProxyCreator txAutoProxyCreator() {
// BeanNameAutoProxyCreator proxyCreator = new BeanNameAutoProxyCreator();
// proxyCreator.setBeanNames("*Service", "*ServiceImpl");
// proxyCreator.setInterceptorNames("dynamicTransactionInterceptor");
// return proxyCreator;
// }
//}
//

@ -0,0 +1,43 @@
//package egovframework.dataSourece;
//
//import org.springframework.transaction.PlatformTransactionManager;
//import org.springframework.transaction.TransactionDefinition;
//import org.springframework.transaction.TransactionStatus;
//import org.springframework.transaction.support.DefaultTransactionStatus;
//
//import java.util.Map;
//
//public class DynamicTransactionManager implements PlatformTransactionManager {
//
// private final Map<String, PlatformTransactionManager> transactionManagerMap;
// private final PlatformTransactionManager defaultTransactionManager;
//
// public DynamicTransactionManager(Map<String, PlatformTransactionManager> transactionManagerMap,
// PlatformTransactionManager defaultTransactionManager) {
// this.transactionManagerMap = transactionManagerMap;
// this.defaultTransactionManager = defaultTransactionManager;
// }
//
// private PlatformTransactionManager resolveTransactionManager() {
// String key = DataSourceContextHolder.get();
// if (key == null) {
// return defaultTransactionManager;
// }
// return transactionManagerMap.getOrDefault(key, defaultTransactionManager);
// }
//
// @Override
// public TransactionStatus getTransaction(TransactionDefinition definition) {
// return resolveTransactionManager().getTransaction(definition);
// }
//
// @Override
// public void commit(TransactionStatus status) {
// resolveTransactionManager().commit(status);
// }
//
// @Override
// public void rollback(TransactionStatus status) {
// resolveTransactionManager().rollback(status);
// }
//}

@ -0,0 +1,13 @@
//package egovframework.dataSourece;
//
//import javax.transaction.Transactional;
//import java.lang.annotation.ElementType;
//import java.lang.annotation.Retention;
//import java.lang.annotation.RetentionPolicy;
//import java.lang.annotation.Target;
//
//@Target({ElementType.METHOD, ElementType.TYPE})
//@Retention(RetentionPolicy.RUNTIME)
//@Transactional // 기존 스프링 트랜잭션 어노테이션 상속
//public @interface DynamicTransactional {
//}

@ -2,16 +2,23 @@ package go.kr.project;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@Slf4j
@ServletComponentScan
@SpringBootApplication
@ComponentScan(basePackages = {"go.kr.project", "egovframework"})
@EnableAsync(proxyTargetClass = true)
@EnableTransactionManagement(proxyTargetClass = true)
@EnableCaching(proxyTargetClass = true)
public class CleanParkingApplication extends SpringBootServletInitializer {
@Override

@ -143,8 +143,6 @@ public class LoginController {
try {
SessionVO sessionVO = null;
Object conn = TransactionSynchronizationManager.getResource(dataSource);
log.info("현재 thread에 커넥션 있는가? {}", conn != null);
// 로그인 처리
if(kind.equals("cp")){
DataSourceContextHolder.set("cp");

@ -79,7 +79,7 @@ public class LoginServiceImpl extends EgovAbstractServiceImpl implements LoginSe
* @throws Exception
*/
// cp ep 동적 데이터소스 바인딩을 해야함. 트렌젝션 한단계 안에서 해야할듯.
@Transactional
// @Transactional
@Override
public SessionVO login(String userAcnt, String passwd, String kind, HttpServletRequest request, HttpServletResponse response) throws Exception {
// 비정상적인 로그인 패턴 감지 (과도한 로그인 시도, 다양한 IP에서의 접근 등)

@ -45,7 +45,6 @@ public class LoginLogServiceImpl extends EgovAbstractServiceImpl implements Logi
* @return
*/
@Override
@Transactional
public LoginLogVO recordLoginSuccess(String userId, String userAcnt, HttpServletRequest request) {
LoginLogVO loginLog = createLoginLog(userId, userAcnt, request);
loginLog.setSuccessYn("Y");

Loading…
Cancel
Save