μ½μνΈ λκΈ°μ΄ μλΉμ€λ₯Ό κ°λ°νλ©΄μ ν ν°μ λ§λ£ μ€μΌμ€λ§μ μμ νλ©΄μ κ³ λ―Όνλ λ΄μ©μ΄λ€.
κ°μ μκ°μ λΆμ° νκ²½μμ μ ν리μΌμ΄μ μλ²λ€μ μ€μΌμ€λ§ μ€λ³΅ μ€νμ λ°©μ§νκΈ° μν΄ shed lock μ μ μ©νλ€.
μ²μ μ μ©ν΄λ³Έ κ°λ μ κ΄ν΄ μ 리νκΈ° μν΄ μμ±ν κΈμ΄λ€.
GitHub - pbg0205/concert
Contribute to pbg0205/concert development by creating an account on GitHub.
github.com
[1] ShedLock?
ShedLockμ λΆμ° μμ€ν μμ μ€μΌμ€λ¬ μμ (Scheduled Tasks)μ μ€λ³΅ μ€ν λ°©μ§λ₯Ό μν΄ μ¬μ©λλ λΌμ΄λΈλ¬λ¦¬μ΄λ€. μ¬λ¬ μΈμ€ν΄μ€μμ μ€νλλ μ ν리μΌμ΄μ μ΄ λμΌν μ€μΌμ€λ¬ μμ μ λμμ μ€ννμ§ μλλ‘ λ½(Lock)μ μ¬μ©νμ¬ μ μ΄νλ€.
- λΆμ° νκ²½ μ§μ : ShedLock μ μ¬λ¬ μλ² μΈμ€ν΄μ€μμ νλμ μ€μΌμ€λ¬ μμ μ κ΄ν μ€νμ 보μ₯νλ€.
- λ€μν μ€ν λ¦¬μ§ μ 곡 : λ°μ΄ν°λ² μ΄μ€(MySQL, PostgreSQL λ±) Redis, DynamoDB λ±μ λ€μν μ μ₯μλ₯Ό λ½ μ μ₯μλ‘ μ¬μ©νκ³ LockProvider λ₯Ό ꡬννμ¬ λ§μΆ€ν μ μ₯μλ₯Ό μ€μ ν μ μμ΄ λμ νμ₯μ±μ μ 곡νλ€.
- μλ λ§λ£ λ½ μ 곡 : μ§μ λ μκ°μ΄ μ§λλ©΄ λ½μ΄ μλμ ν΄μ λλ―λ‘ μμ μ€λ¨ λ¬Έμ λ₯Ό λ°©μ§ν μ μλ€.

[2] ShedLock λ₯Ό μ μ©ν΄λ³΄μ.
ShedLock GitHub μμ μ 곡νλ νν 리μΌμ κ΄ν΄ μ€λͺ μ΄ μλμ΄ μλ€. μ΄λ₯Ό κΈ°λ°μΌλ‘ ShedLock μ μ μ©ν΄λ³΄μ.
GitHub - lukas-krecan/ShedLock: Distributed lock for your scheduled tasks
Distributed lock for your scheduled tasks. Contribute to lukas-krecan/ShedLock development by creating an account on GitHub.
github.com
(1) build.gradle
- ShedLock μ Spring Boot νκ²½μμ μ¬μ΄ μ€μ κ³Ό μ¬μ©μ΄ κ°λ₯νλ€. Spring μμ ShedLock μ μ¬μ©νκ³ μ νλ κ²½μ°, shedlock-spring μ νΈννλ μ€νλ§ λ²μ μ λ§κ² μ μ©νλλ‘νμ.
- νμ¬ νλ‘μ νΈμμλ RDB μ Lock data λ₯Ό κ΄λ¦¬ν μμ μ΄λ―λ‘ shedlock-provider-jdbc-template λ₯Ό μ¬μ©νλ€.
dependencies {
// Shed lock
implementation 'net.javacrumbs.shedlock:shedlock-provider-jdbc-template:6.2.0'
implementation 'net.javacrumbs.shedlock:shedlock-spring:6.2.0'
}
(2) shedlock schema μΆκ°νκΈ°
shedlock data λ₯Ό κ΄λ¦¬νκΈ° μν΄μ λ³λμ ν μ΄λΈ μ μΈμ΄ νμνλ€. ν μ΄λΈμ κ΄ν μ 보λ shedlock GitHub μμ μ 곡νκ³ μμΌλ μ°Έκ³ νλλ‘ νμ. (RDB μμλ Named Lock μΌλ‘ λμνλ κ² κ°λ€.)
# MySQL, MariaDB
CREATE TABLE shedlock(
name VARCHAR(64) NOT NULL,
lock_until TIMESTAMP(3) NOT NULL,
locked_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
locked_by VARCHAR(255) NOT NULL,
PRIMARY KEY (name));
(3) LockProvider μΆκ°νκΈ°
- ShedLock μ νμ±ννκΈ° μν΄μλ @EnableSchedulerLock μ μ μΈν΄μΌ νλ€.
- @EnableSchedulerLock μ defaultLockAtMostFor μ΅μ μ μ€μ ν΄μΌ νλ€.
- λ½μ μ΅λ μ μ μκ°μ μ€μ νλ μ΅μ μ΄λ μλΉμ€ νκ²½μ λ§κ² μ€μ νλ©΄ λ κ² κ°λ€.
- Lock data λ₯Ό κ΄λ¦¬νκΈ° μν΄μλ LockProvicer λ₯Ό μ€μ ν΄μΌ νλ€.
- νμ¬λ RDB λ₯Ό κΈ°λ°μΌλ‘ μ¬μ©ν μμ μ΄λ―λ‘ JdbcTemplateLockProvicer λ₯Ό μ μ©νλ€.
@Configuration
@EnableScheduling
@EnableSchedulerLock(defaultLockAtMostFor = "10m")
public class ScheduleConfig {
@Bean
public LockProvider lockProvider(final DataSource dataSource) {
return new JdbcTemplateLockProvider(dataSource, "shedlock"); // datasource + table μ΄λ¦
}
}
(3) ShedLock μ μ©νκΈ°
- μ€νν μ€μΌμ€λ§μ @SchedulerLock μ μΈνλ€.
- name : λ½μ key name μ μ€μ νλ μ΅μ μ΄λ€.
- lockAtLeastFor : λ½μ μ μ ν μ΅μ μκ°μ μ€μ νλ μ΅μ μ΄λ€.
- lockAtMostFor : λ½μ μ μ ν μ΅λ μκ°μ μ€μ νλ μ΅μ μ΄λ€. μ΅λ μκ°μ μ΄κ³Όνλ κ²½μ° μλμΌλ‘ λ½μ ν΄μ νλ€.
(μκ°μ κ΄λ ¨λ μ€μ μ duration+unit / duration in ms / ISO-8601 μ μ§μνλ―λ‘ μμΈν λ΄μ©μ ν΄λΉ λ§ν¬λ₯Ό μ°Έκ³ νμ.)
@Scheduler
@RequiredArgsConstructor
public class TokenScheduler {
private final TokenSchedulerUseCase tokenSchedulerUseCase;
@SchedulerLog
@Scheduled(fixedRateString = "${queue.processing.rate}", timeUnit = TimeUnit.SECONDS)
@SchedulerLock(name = "tokenActiveScheduler", lockAtLeastFor = "PT5S", lockAtMostFor = "PT8S")
public Integer tokenActiveScheduler() {
return tokenSchedulerUseCase.updateToProcessing(LocalDateTime.now());
}
}
(4) ShedLock μ μ© νμΈνκΈ°
local νκ²½μμ μ μμ μΌλ‘ μ€μΌμ€λ§μ λ¨μΌ μ€νμ ν μ€νΈνκΈ° μν΄ program argument(--server.port) μ μ¬μ©ν΄ λ κ°μ
application μ μ€νν΄ λ¨μΌ μ€μΌμ€λ§μ νμΈν΄λ³Ό μ μμλ€.
java -jar build/libs/concert-0.0.1-SNAPSHOT.jar --server.port=8080
java -jar build/libs/concert-0.0.1-SNAPSHOT.jar --server.port=8081

μ°Έκ³
lock data λ key name λΉ νλμ λ‘μ°λ₯Ό κ΄λ¦¬νλ€.
λ§μ½ ν΄λΉ ν€ μ΄λ¦μ shedlock μ΄ ν΄μ λκ³ μ κΈμ΄ νμ±νλλ©΄ ν΄λΉ λ‘μ°(row)λ₯Ό μ λ°μ΄νΈνλ λ°©μμΌλ‘ λμνλ€.

'π backend > spring' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
| Spring6.1 λΆν° λ³κ²½λ Parameter Name Retention (0) | 2025.03.11 |
|---|---|
| 컀μ€ν μ΄λ Έν μ΄μ κΈ°λ° AOP λ₯Ό @Transactional λ³΄λ€ λμ€μ μ€νμν€κΈ° (0) | 2025.01.27 |
| Spring REST Docs + Swagger UI λ₯Ό ν΅ν API λ¬Έμν (0) | 2024.12.07 |
| λΉκ΄μ λ½ vs λκ΄μ λ½(In JPA) (0) | 2024.11.28 |
| MessageSourceAutoConfiguration μ½λ κ²ν νκΈ° (0) | 2024.11.28 |
