Skip to content

Commit

Permalink
[BE] DB read, write 쿼리 트래픽을 분리해요 (#360)
Browse files Browse the repository at this point in the history
* chore: 서브모듈 변경사항 반영

* feat: `@Transactional` readOnly 설정 별 DB 트랜잭션 분산 로직 추가

* feat: 읽기 쿼리에 대해 `@Transactional` readOnly 설정 추가

* refactor(DataSourceConfig): `Map.of()` 수정
  • Loading branch information
ikjo39 authored Sep 26, 2024
1 parent 8797d85 commit 3c53afe
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 1 deletion.
56 changes: 56 additions & 0 deletions backend/src/main/java/kr/momo/config/DataSourceConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package kr.momo.config;

import java.util.Map;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Profile;
import org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy;

@Configuration
@Profile("prod")
public class DataSourceConfig {

public static final String SOURCE_SERVER = "source";
public static final String REPLICA_SERVER = "replica";

@Bean(SOURCE_SERVER)
@ConfigurationProperties(prefix = "spring.datasource.source")
public DataSource sourceDataSource() {
return DataSourceBuilder.create()
.build();
}

@Bean(REPLICA_SERVER)
@ConfigurationProperties(prefix = "spring.datasource.replica")
public DataSource replicaDataSource() {
return DataSourceBuilder.create()
.build();
}

@Bean
public DataSource routingDataSource(
@Qualifier(SOURCE_SERVER) DataSource source,
@Qualifier(REPLICA_SERVER) DataSource replica
) {
RoutingDataSource routingDataSource = new RoutingDataSource();
Map<Object, Object> dataSourceMap = Map.of(
SOURCE_SERVER, source,
REPLICA_SERVER, replica
);
routingDataSource.setTargetDataSources(dataSourceMap);
routingDataSource.setDefaultTargetDataSource(source);
return routingDataSource;
}

@Bean
@Primary
public DataSource dataSource() {
DataSource dataSource = routingDataSource(sourceDataSource(), replicaDataSource());
return new LazyConnectionDataSourceProxy(dataSource);
}
}
15 changes: 15 additions & 0 deletions backend/src/main/java/kr/momo/config/RoutingDataSource.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package kr.momo.config;

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import org.springframework.transaction.support.TransactionSynchronizationManager;

public class RoutingDataSource extends AbstractRoutingDataSource {

@Override
protected Object determineCurrentLookupKey() {
if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
return DataSourceConfig.REPLICA_SERVER;
}
return DataSourceConfig.SOURCE_SERVER;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ private AttendeeLoginResponse signup(Meeting meeting, AttendeeName name, Attende
return AttendeeLoginResponse.from(jwtManager.generate(attendee.getId()), attendee);
}

@Transactional(readOnly = true)
public List<String> findAll(String uuid) {
Meeting meeting = meetingRepository.findByUuid(uuid)
.orElseThrow(() -> new MomoException(MeetingErrorCode.INVALID_UUID));
Expand Down
2 changes: 1 addition & 1 deletion backend/src/main/resources/security

0 comments on commit 3c53afe

Please sign in to comment.