[#52] 만료 예약 / 일정 스케쥴링 작업 추가 및 동시성 처리를 위한 일부 코드 수정 #53

Merged
pricelees merged 18 commits from refactor/#52 into main 2025-10-04 08:40:37 +00:00
6 changed files with 54 additions and 21 deletions
Showing only changes of commit 99917df600 - Show all commits

View File

@ -0,0 +1,33 @@
package com.sangdol.roomescape.common.config
import io.github.oshai.kotlinlogging.KLogger
import io.github.oshai.kotlinlogging.KotlinLogging
import jakarta.annotation.PreDestroy
import jakarta.transaction.Transactional
import org.springframework.context.annotation.Profile
import org.springframework.jdbc.core.JdbcTemplate
import org.springframework.stereotype.Component
private val log: KLogger = KotlinLogging.logger {}
@Component
@Profile("local")
class LocalDatabaseCleaner(
private val jdbcTemplate: JdbcTemplate
) {
@PreDestroy
@Transactional
fun clearAll() {
log.info { "[LocalDatabaseCleaner] 데이터베이스 초기화 시작" }
jdbcTemplate.execute("SET FOREIGN_KEY_CHECKS = 0")
jdbcTemplate.query("SHOW TABLES") { rs, _ ->
rs.getString(1).lowercase()
}.forEach {
jdbcTemplate.execute("TRUNCATE TABLE $it")
}
jdbcTemplate.execute("SET FOREIGN_KEY_CHECKS = 1")
log.info { "[LocalDatabaseCleaner] 데이터베이스 초기화 완료" }
}
}

View File

@ -5,20 +5,16 @@ spring:
format_sql: true format_sql: true
hibernate: hibernate:
ddl-auto: validate ddl-auto: validate
h2:
console:
enabled: true
path: /h2-console
datasource: datasource:
hikari: hikari:
jdbc-url: jdbc:h2:mem:database jdbc-url: jdbc:mysql://localhost:23306/roomescape_local
driver-class-name: org.h2.Driver driver-class-name: com.mysql.cj.jdbc.Driver
username: sa username: root
password: password: init
sql: sql:
init: init:
mode: always mode: always
schema-locations: classpath:schema/schema-h2.sql schema-locations: classpath:schema/schema-mysql.sql
data-locations: classpath:schema/region-data.sql data-locations: classpath:schema/region-data.sql
security: security:

View File

@ -1,10 +1,10 @@
package com.sangdol.data package com.sangdol.data
import com.sangdol.common.persistence.IDGenerator import com.sangdol.common.persistence.IDGenerator
import com.sangdol.common.persistence.TransactionExecutionUtil
import com.sangdol.roomescape.admin.infrastructure.persistence.AdminEntity import com.sangdol.roomescape.admin.infrastructure.persistence.AdminEntity
import com.sangdol.roomescape.admin.infrastructure.persistence.AdminPermissionLevel import com.sangdol.roomescape.admin.infrastructure.persistence.AdminPermissionLevel
import com.sangdol.roomescape.admin.infrastructure.persistence.AdminType import com.sangdol.roomescape.admin.infrastructure.persistence.AdminType
import com.sangdol.common.persistence.TransactionExecutionUtil
import com.sangdol.roomescape.payment.infrastructure.common.* import com.sangdol.roomescape.payment.infrastructure.common.*
import com.sangdol.roomescape.reservation.infrastructure.persistence.ReservationStatus import com.sangdol.roomescape.reservation.infrastructure.persistence.ReservationStatus
import com.sangdol.roomescape.schedule.infrastructure.persistence.ScheduleStatus import com.sangdol.roomescape.schedule.infrastructure.persistence.ScheduleStatus
@ -32,7 +32,7 @@ import java.time.LocalDateTime
import java.time.LocalTime import java.time.LocalTime
import java.time.OffsetDateTime import java.time.OffsetDateTime
@ActiveProfiles("test", "test-mysql") @ActiveProfiles("test", "data")
abstract class AbstractDataInitializer( abstract class AbstractDataInitializer(
val semaphore: Semaphore = Semaphore(permits = 10), val semaphore: Semaphore = Semaphore(permits = 10),
) : FunSpecSpringbootTest( ) : FunSpecSpringbootTest(

View File

@ -23,22 +23,26 @@ class TestDatabaseUtil(
} }
fun initializeRegion() { fun initializeRegion() {
this::class.java.getResource("/schema/region-data.sql")?.readText()?.let { jdbcTemplate.queryForObject("SELECT EXISTS (SELECT 1 FROM region LIMIT 1)", Boolean::class.java)!!.also { isRegionTableEmpty ->
jdbcTemplate.execute(it) if (!isRegionTableEmpty) {
this::class.java.getResource("/schema/region-data.sql")?.readText()?.let { regionInsertSql ->
jdbcTemplate.execute(regionInsertSql)
}
}
} }
} }
fun clear(mode: CleanerMode) { fun clear(mode: CleanerMode) {
entityManager.clear() entityManager.clear()
jdbcTemplate.execute("SET REFERENTIAL_INTEGRITY FALSE") jdbcTemplate.execute("SET FOREIGN_KEY_CHECKS = 0")
tables.forEach { tables.forEach {
if (mode == CleanerMode.EXCEPT_REGION && it == "region") { if (mode == CleanerMode.EXCEPT_REGION && it == "region") {
return@forEach return@forEach
} }
jdbcTemplate.execute("TRUNCATE TABLE $it RESTART IDENTITY") jdbcTemplate.execute("TRUNCATE TABLE $it")
} }
jdbcTemplate.execute("SET REFERENTIAL_INTEGRITY TRUE") jdbcTemplate.execute("SET FOREIGN_KEY_CHECKS = 1")
} }
} }

View File

@ -10,14 +10,14 @@ spring:
ddl-auto: validate ddl-auto: validate
datasource: datasource:
hikari: hikari:
jdbc-url: jdbc:h2:mem:test jdbc-url: jdbc:mysql://localhost:23306/roomescape_local
driver-class-name: org.h2.Driver driver-class-name: com.mysql.cj.jdbc.Driver
username: sa username: root
password: password: init
sql: sql:
init: init:
mode: always mode: always
schema-locations: classpath:schema/schema-h2.sql schema-locations: classpath:schema/schema-mysql.sql
security: security:
jwt: jwt: