Home > Code Review > πŸ’»[Code Review] MySQLConfig 클래슀 μ½”λ“œ 리뷰.

πŸ’»[Code Review] MySQLConfig 클래슀 μ½”λ“œ 리뷰.
Code review

πŸ’»[Code Review] MySQLConfig 클래슀 μ½”λ“œ 리뷰.

1️⃣ 전체 μ½”λ“œ.

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.support.TransactionTemplate;

import javax.sql.DataSource;

@Configuration
@EnableTransactionManagement
public class MySQLConfig {

    @Value("${spring.datasource.url}")
    private String url;

    @Value("${spring.datasource.username}")
    private String username;

    @Value("${spring.datasource.password}")
    private String password;

    @Value("${spring.datasource.driver-class-name}")
    private String driverClassName;

    @Bean
    public DataSourceTransactionManager transactionManager(DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean
    public TransactionTemplate transactionTemplate(PlatformTransactionManager transactionManager) {
        return new TransactionTemplate(transactionManager);
    }

    @Bean(name = "createUserTransactionManager")
    public PlatformTransactionManager createUserTranscationManager(DataSource dataSource) {
        DataSourceTransactionManager manager = new DataSourceTransactionManager(dataSource);
        return manager;
    }
}

2️⃣ μ½”λ“œ 리뷰 - μƒμ„Έν•˜κ²Œ λœ―μ–΄λ³΄κΈ° πŸ”

1️⃣ 클래슀 μ„ μ–ΈλΆ€.

@Configuration
@EnableTransactionManagement
public class MySQLConfig {...
  • @Configuration
    • 이 ν΄λž˜μŠ€κ°€ Spring의 μ„€μ • ν΄λž˜μŠ€μž„μ„ λ‚˜νƒ€λƒ…λ‹ˆλ‹€.
    • @Bean μ–΄λ…Έν…Œμ΄μ…˜μ΄ μžˆλŠ” λ©”μ„œλ“œλ“€μ„ 톡해 Bean을 생성 및 λ“±λ‘ν•©λ‹ˆλ‹€.
  • @EnableTransactioonManagement
    • μŠ€ν”„λ§μ—μ„œ 선언적 νŠΈλžœμž­μ…˜ 관리λ₯Ό ν™œμ„±ν™”ν•©λ‹ˆλ‹€.
    • @Transactional μ–΄λ…Έν…Œμ΄μ…˜μ„ μ‚¬μš©ν•˜λŠ” νŠΈλžœμž­μ…˜ 관리λ₯Ό μ§€μ›ν•˜λ„λ‘ μ„€μ •ν•©λ‹ˆλ‹€.

2️⃣ 속성 μ£Όμž…

    @Value("${spring.datasource.url}")
    private String url;

    @Value("${spring.datasource.username}")
    private String username;

    @Value("${spring.datasource.password}")
    private String password;

    @Value("${spring.datasource.driver-class-name}")
    private String driverClassName;
  • @Value
    • Spring application.properties λ˜λŠ” application.yml νŒŒμΌμ— μ •μ˜λœ μ„€μ • 값을 κ°€μ Έμ˜΅λ‹ˆλ‹€.
    • 예λ₯Ό λ“€μ–΄, application.properties에 μ•„λž˜μ™€ 같은 ν•­λͺ©μ΄ μ •μ˜ λ˜μ–΄ 있으면:
        spring.datasource.url=jdbc:mysql://localhost:3306/mydb
        spring.datasource.username=root
        spring.datasource.password=1234
        spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
      
    • 이 값듀이 url, username, password, driverClassName ν•„λ“œμ— μ£Όμž…λ©λ‹ˆλ‹€.

3️⃣ νŠΈλžœμž­μ…˜ λ§€λ‹ˆμ € 생성.

@Bean
public DataSourceTransactionManager transactionManager(DataSource dataSource) {
    return new DataSourceTransactionManager(dataSource);
}
  • @Bean
    • 이 λ©”μ„œλ“œκ°€ λ°˜ν™˜ν•˜λŠ” 객체(DataSourceTransactionManager)λ₯Ό Spring의 Bean으둜 λ“±λ‘ν•©λ‹ˆλ‹€.
  • DataSourceTransactionManager
    • λ°μ΄ν„°λ² μ΄μŠ€ νŠΈλžœμž­μ…˜μ„ κ΄€λ¦¬ν•˜λŠ” Spring의 κΈ°λ³Έ νŠΈλžœμž­μ…˜ λ§€λ‹ˆμ € ν΄λž˜μŠ€μž…λ‹ˆλ‹€.
    • DataSource 객체λ₯Ό λ°›μ•„μ„œ νŠΈλžœμž­μ…˜μ„ κ΄€λ¦¬ν•©λ‹ˆλ‹€.
    • DataSourceλŠ” JDBCλ₯Ό 톡해 MySQL λ°μ΄ν„°λ² μ΄μŠ€ 연결을 μ œκ³΅ν•©λ‹ˆλ‹€.

4️⃣ νŠΈλžœμž­μ…˜ ν…œν”Œλ¦Ώ 생성.

@Bean
public TransactionTemplate transactionTemplate(PlatformTransactionManager transactionManager) {
    return new TransactionTemplate(transactionManager);
}
  • TransactionTemplate
    • ν”„λ‘œκ·Έλž˜λ° λ°©μ‹μœΌλ‘œ νŠΈλžœμž­μ…˜ 관리λ₯Ό μ§€μ›ν•˜λŠ” ν…œν”Œλ¦Ώ ν΄λž˜μŠ€μž…λ‹ˆλ‹€.
    • PlatformTransactionManagerλ₯Ό μ‚¬μš©ν•˜μ—¬ νŠΈλžœμž­μ…˜μ˜ μ‹œμž‘, 컀밋, λ‘€λ°± 등을 κ΄€λ¦¬ν•©λ‹ˆλ‹€.
    • 선언적 νŠΈλžœμž­μ…˜(@Transaction) λŒ€μ‹  ν”„λ‘œκ·Έλž˜λ° λ°©μ‹μœΌλ‘œ νŠΈλžœμž­μ…˜μ„ μ œμ–΄ν•˜κ³ μž ν•  λ•Œ μ‚¬μš©λ©λ‹ˆλ‹€.

5️⃣ 좔가적이 νŠΈλžœμž­μ…˜ λ§€λ‹ˆμ € 등둝.

@Bean(name = "createUserTransactionManager")
public PlatformTransactionManager createUserTransactionManager(DataSource dataSource) {
    DataSourceTransactionManager manager = new DataSourceTransactionManager(dataSource);
    return manager;
}
  • λ³„λ„μ˜ νŠΈλžœμž­μ…˜ λ§€λ‹ˆμ € 등둝
    • @Bean(name = "createUserTransactionManager")둜 μ§€μ •ν•˜μ—¬ λ‹€λ₯Έ μ΄λ¦„μ˜ νŠΈλžœμž­μ…˜ λ§€λ‹ˆμ €λ₯Ό λ“±λ‘ν•©λ‹ˆλ‹€.
    • μ΄λ ‡κ²Œ ν•˜λ©΄ μ—¬λŸ¬ λ°μ΄ν„°λ² μ΄μŠ€ λ˜λŠ” νŠΉμ • μž‘μ—…μ— λŒ€ν•΄ λ‹€λ₯Έ νŠΈλžœμž­μ…˜ λ§€λ‹ˆμ €λ₯Ό μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
    • 이 Bean은 ν•„μš”μ— 따라 μ˜μ‘΄μ„± μ£Όμž… μ‹œ μ΄λ¦„μœΌλ‘œ μ°Έμ‘°ν•  수 μžˆμŠ΅λ‹ˆλ‹€:
        @Autowired
        @Qualifier("createUserTransactionManager")
        private PlatformTransactionManager transactionManager;
      

3️⃣ 이 μ½”λ“œμ˜ μ£Όμš” κΈ°λŠ₯.

1️⃣ λ°μ΄ν„°λ² μ΄μŠ€ νŠΈλžœμž­μ…˜ 관리.

  • λ°μ΄ν„°λ² μ΄μŠ€ μž‘μ—… μ‹œ νŠΈλžœμž­μ…˜(μ‹œμž‘, 컀밋, λ‘€λ°±)을 μ œμ–΄ν•©λ‹ˆλ‹€.

2️⃣ 선언적 및 ν”„λ‘œκ·Έλž˜λ°μ  νŠΈλžœμž­μ…˜ 지원.

  • @Transactional둜 선언적 νŠΈλžœμž­μ…˜μ„ μ§€μ›ν•˜λ©°, TransactionTemplate을 톡해 ν”„λ‘œκ·Έλž˜λ° λ°©μ‹μœΌλ‘œ νŠΈλžœμž­μ…˜μ„ 관리할 수 μžˆμŠ΅λ‹ˆλ‹€.

3️⃣ μœ μ—°ν•œ νŠΈλžœμž­μ…˜ λ§€λ‹ˆμ €.

  • ν•˜λ‚˜ μ΄μƒμ˜ νŠΈλžœμž­μ…˜ λ§€λ‹ˆμ €λ₯Ό μ •μ˜ν•˜μ—¬ λ‹€μ–‘ν•œ νŠΈλžœμž­μ…˜ 관리 μš”κ΅¬λ₯Ό μΆ©μ‘±ν•©λ‹ˆλ‹€.

4️⃣ μΆ”κ°€λ‘œ μ•Œμ•„λ‘λ©΄ 쒋은 점.

1️⃣ 닀쀑 λ°μ΄ν„°λ² μ΄μŠ€ ν™˜κ²½.

  • 두 개 μ΄μƒμ˜ λ°μ΄ν„°λ² μ΄μŠ€λ₯Ό μ‚¬μš©ν•˜λŠ” 경우, 각각의 λ°μ΄ν„°μ†ŒμŠ€μ™€ νŠΈλžœμž­μ…˜ λ§€λ‹ˆμ €λ₯Ό λ³„λ„λ‘œ μ„€μ •ν•˜μ—¬ 관리할 수 μžˆμŠ΅λ‹ˆλ‹€.

2️⃣ DataSource Bean 생성.

  • 이 μ½”λ“œμ—μ„œλŠ” DataSourceκ°€ μ£Όμž…λœλ‹€κ³  κ°€μ •ν–ˆμ§€λ§Œ, DataSourceλ₯Ό 직접 μƒμ„±ν•˜λ €λ©΄ λ³„λ„μ˜ Bean μ •μ˜κ°€ ν•„μš”ν•©λ‹ˆλ‹€:
      @Bean
      public DataSource dataSource() {
          HikariDataSource dataSource = new HikariDataSource();
          dataSource.setJdbcUrl(url);
          dataSource.setUsername(username);
          dataSource.setPassword(password);
          dataSource.setDriverClassName(driverClassName);
          return dataSource;
      }