๐ ๋ชฉ์ฐจ
SpringBoot๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ด์ปค๋จธ์ค ์๋น์ค๋ฅผ ๊ตฌํํ๋ฉด์ ๋์์ฑ ์ด์๊ฐ ๋ฐ์ํ๋ค.
Redis์ Redisson๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ด์ฉํด ๋์์ฑ ์ด์๋ฅผ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ์ ๋ํด ์์๋ณด์.
๐ ๋์์ฑ ์ ์ด๋?
๋์์ฑ ์ ์ด(Concurrency Control)๋, ์ฌ๋ฌ ์ค๋ ๋๋ ํ๋ก์ธ์ค๊ฐ ๋ฐ์ดํฐ๋ฅผ ๊ณต์ ํ๋ ์์ ์ด ๋์์ ์คํ๋ ๋ ๊ทธ ์คํ ์์๋ ์กฐ๊ฑด์ ์ ์ดํ์ฌ ๋ฐ์ดํฐ์ ๋ฌด๊ฒฐ์ฑ์ ์ ์งํ๊ณ ์์์น ๋ชปํ ๋์์ ๋ฐฉ์งํ๋ ๊ฒ์ ๋งํ๋ค. ์ฌ๋ฌ ์์ ๊ฐ์ ์ํธ์์ฉ, ์์ ๊ณต์ , ๊ฒฝ์ ์กฐ๊ฑด ๋ฑ์ ๊ด๋ฆฌํ์ฌ ํ๋ก๊ทธ๋จ์ ์์ ์ฑ๊ณผ ์ฑ๋ฅ์ ๋ณด์ฅํ๋ ๋ฐ ์ค์ํ ์ญํ ์ ํ๋ค.
๐ ๋์์ฑ ์ ์ด์ ๋ชฉ์
- ์ฌ๋ฌ ์ฌ์ฉ์๊ฐ DB์ ์ ๊ทผํ๋๋ผ๋ ๋ฐ์ดํฐ์ ์ผ๊ด์ฑ์ ๋ณด์ฅํ๊ณ ๋ฐ์ดํฐ์ ๋ฌด๊ฒฐ์ฑ์ ์ ์ง
- ์๋ฅผ ๋ง์กฑํ๋ฉฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์คํ ์ ์ฑ๋ฅ๊ณผ ํจ์จ์ฑ์ ์ ์งํ๋ ๊ฒ
๐ ๋์์ฑ ์ ์ด ๊ธฐ๋ฒ
๋์์ฑ ์ด์๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๋ค์ํ ๋ฐฉ๋ฒ์ ์๊ฐํด ๋ณผ ์ ์๋ค. ๋์์ฑ ์ ์ด ๊ธฐ๋ฒ์๋ ์ฌ๋ฌ ๊ฐ์ง๊ฐ ์๋๋ฐ ๊ทธ์ค, Locking๊ธฐ๋ฒ์ ์ ์ฉํด๋ณด๋ ค๊ณ ํ๋ค. Locking๊ธฐ๋ฒ์ ๋ฐ์ดํฐ์ ์ ๊ธ(Lock)์ ์ค์ ํ๋ฉด ๋ค๋ฅธ ํธ๋์ญ์ ์ ํด๋น ๋ฐ์ดํฐ์ ์ ๊ธ์ด ํด์ (UnLock)๋ ๋๊น์ง ์ ๊ทผ, ์์ , ์ญ์ ๊ฐ ๋ถ๊ฐ๋ฅํ๊ฒ ํด๋์ ๋ฐฉ๋ฒ์ด๋ค.
- synchronized
- ํ์ฌ ์ ๊ทผํ๊ณ ์๋ ๋ฉ์๋์ ํ๋์ ์ค๋ ๋๋ง ์ ๊ทผํ ์ ์๋๋ก ๋ณด์ฅ ๋ฐ ๋์ํ๋ค. ์๋ฐ์์ ์ง์ํ๋ค.
- ์ค๋ ๋ ํ๋์ฉ ์์ฐจ์ ์ผ๋ก ๋ฐ์ดํฐ์ ์ ๊ทผํ ์ ์๋๋ก ํด์ค๋ค.
- ์ ํ๋ฆฌ์ผ์ด์ ์ ํ๋๋ง ๋์ฐ๋ ๊ฒฝ์ฐ๋ ๋ฌด๊ดํ์ง๋ง, ์๋ฒ๊ฐ ์ฌ๋ฌ ๋์ผ ๊ฒฝ์ฐ์๋ ์ฌ๋ฌ ๊ฐ์ ์ธ์คํด์ค๊ฐ ์กด์ฌํ๋ ๊ฒ๊ณผ ๋์ผํ๊ธฐ ๋๋ฌธ์ ์ค์ง์ ์ธ ์ด์ ํ๊ฒฝ์์๋ ๋ฐ์ดํฐ์ ์ ํฉ์ฑ์ ๋ณด์ฅํ ์ ์๋ค.
- Pessimistic Lock(๋น๊ด์ ๋ฝ)
- ๋ฐ์ดํฐ์ Lock์ ๊ฑธ์ด์ ์ ํฉ์ฑ์ ๋ง์ถ๋ ๋ฐฉ๋ฒ์ด๋ค. ๋ฐ์ดํฐ๋ฅผ ๋ณ๊ฒฝํ๊ธฐ ์ ์ ๋ฝ์ ํ๋ํ๋ค.
- ํ ๋ฒ์์ฌ๋ฌ ๊ฐ์ ํ ์ด๋ธ์ ์์ ํ๋ ค๊ณ ํ์ ๋, ํ๋์ ํธ๋์ญ์ ์ผ๋ก ๋ฌถ์ฌ์๊ธฐ ๋๋ฌธ์ ์์ ํ๋๊ฐ ์คํจํ๋ฉด ๋ฐ์ดํฐ๋ฒ ์ด์ค๋จ์์ ์ ์ฒด ์๋ ๋กค๋ฐฑ์ด ์ผ์ด๋๊ฒ ๋๋ค.
- ๋์์ ์ฌ๋ฌ ์ฌ์ฉ์๊ฐ ๋ฐ์ดํฐ์ ์ ๊ทผํ ๋ ์ฑ๋ฅ ๋ฌธ์ ๋ฅผ ๋ฐ์์ํฌ ์ ์๋ค.
- ํนํ ๋ฐ์ดํฐ ๋ฒ ์ด์ค๋ ๋ถ์ฐ ์์คํ ์์ ์ฌ์ฉ๋ ๊ฒฝ์ฐ, ๋ฝ์ด ๋ฐ์ํ ๋ ๋ค๋ฅธ ์์ ์ด ๋๊ธฐํด์ผ ํ๋ฏ๋ก ์ฒ๋ฆฌ๋์ด ๊ฐ์ํ ์ ์๋ค.
- Optimistic Lock(๋๊ด์ ๋ฝ)
- ๋น๊ด์ ๋ฝ๊ณผ ๋ค๋ฅด๊ฒ ํธ๋์ญ์ ์ ์ก์ง ์๊ธฐ ๋๋ฌธ์ ์ถฉ๋ ๊ฐ์ง๋ฅผ ํ ์ ์๋ค. ์ฑ๋ฅ์ ์ผ๋ก๋ ๋น๊ด์ ๋ฝ๋ณด๋ค ์ข๋ค.
- ์ถฉ๋์ด ๋ฐ์ํ์ฌ ์์ ์ ๋ชปํ ๋ถ๋ถ์ ๋ํด์๋ ๋กค๋ฐฑ์ ๋ํ ์ฑ ์์ ์ ํ๋ฆฌ์ผ์ด์ ๋จ์์ ์ง๋ฉฐ, ์ ํ๋ฆฌ์ผ์ด์ ์์ ์๋์ผ๋ก ๋กค๋ฐฑ์ ํด์ค์ผ ํ๋ค.
- ์ถฉ๋์ด ๋ง์ด ์์๋๊ฑฐ๋ ์ถฉ๋์ด ๋ฐ์ํ์ ๋, ๋น์ฉ์ด ๋ง์ด ๋ค ๊ฒ์ด๋ผ๊ณ ํ๋จ๋๋ ๊ณณ์์๋ ์ฌ์ฉํ์ง ์๋ ๊ฒ์ด ์ข๋ค.
- ์ํฐํฐ์ @Version์ ์ถ๊ฐํด์ฃผ์ด์ผ ํ๋ค. ์กฐํ์ ๊ฐฑ์ ์ ๋ฒ์ ๋น๊ต๋ฅผ ํตํด์ ์ ํฉ์ฑ์ ๋ง์ถ๋ค.
- Named Lock
- ๋ง ๊ทธ๋๋ก ์ด๋ฆ์ ๊ฐ์ง Lock์ด๋ค. ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ณ๋์ ์ ์ฅ์์ ์ด๋ฆ์ ๊ฐ์ง ๋ฝ์ ์ ์ฅํ๊ณ , ํด๋น ์ด๋ฆ์ ๋ํ ๋ฝ์ ํด์ ๋๊ธฐ ์ ๊น์ง๋ ๋ค๋ฅธ ํธ๋์ญ์ ์์ ๋ฝ์ ํ๋ํ ์ ์๋ค.
- ๋ณดํต ๋ถ์ฐ๋ฝ์์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ด๋ฉฐ, MySQL์์๋ง ์ฌ์ฉ์ด ๊ฐ๋ฅํ๋ค.
- ๋ฝ์ ์ฌ์ฉํ๊ธฐ ์ํด ๋ณ๋์ ์ปค๋ฅ์ ํ์ ๊ด๋ฆฌํด์ผ ํ๊ณ , ๋ฝ์ ๊ด๋ จ๋ ๋ถํ๋ฅผ RDS์์ ๋ฐ๋๋ค๋ ๋จ์ ์ด ์๋ค.
- Lettuce
- redis๋ฅผ dependency์ ์ถ๊ฐํ๋ฉด ๋ณ๋์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ค์น ์์ด ์ฌ์ฉํ ์ ์๋ค.
- ์คํ ๋ฝ ๋ฐฉ์์ผ๋ก ๋์์ ๋ง์ ์ค๋ ๋๊ฐ ๋ฝ ํ๋์ ๋๊ธฐ ์ค์ด๋ผ๋ฉด, redis ์๋ฒ์ ๋ถํ๋ฅผ ๋ฐ์์ํฌ ์ ์๋ค.
- redis์ ๊ฐ์ด ์กด์ฌํ์ง ์์ผ๋ฉด ์ธํ ํ๊ฒ ํ๊ณ , ๊ฐ์ด ์ธํ ๋์๋์ง ์ฌ๋ถ๋ฅผ ๋ฆฌํด ๊ฐ์ผ๋ก ๋ฐ์ ๋ฝ์ ํ๋ํ๋ ๋ฐ ์ฑ๊ณตํ๋ค. ๋ฝ์ ์ ์ ํ๋ ์๊ฐ์ด ์งง์ผ๋ฉด ์ ๋ฆฌํ์ง๋ง ์ค๋ ๋๊ฐ ๋ฝ์ ์ค๋ ์ ์ ํ๊ณ ์๋ ๊ฒฝ์ฐ CPU์ ๋ถ๋ด์ ์ค ์ ์๋ค.
- ๋ฝ์ ๋ง๋ฃ ์๊ฐ์ ์ง์ ํ ์ ์๊ธฐ ๋๋ฌธ์ ๋ฝ ํ๋์ ๋ํ ์ฌ์๋๊ฐ ํ์ ์๋ ๊ฒฝ์ฐ์ ์ฌ์ฉํ๋ฉด ์ข๋ค.
- Redisson
- ๋ณ๋์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ถ๊ฐํด์ผ ์ฌ์ฉํ ์ ์๋ค.
- Pub/Sub๊ธฐ๋ฅ์ ์ฌ์ฉํ์ฌ ์คํ ๋ฝ์ด redis์ ์ฃผ๋ ์์ฒญ๋ ํธ๋ํฝ์ ์ค์๋ค.
- ๋ฝ์ ๋ง๋ฃ ์๊ฐ์ ์ง์ ํ ์ ์์ด, ๋ฝ ํ๋์ ์ฌ์๋ํด์ผ ํ๋ ๊ฒฝ์ฐ์ ์ฌ์ฉํ๋ฉด ์ข๋ค.
โ๏ธ ์์ ๋ฐฉ๋ฒ๋ค ์ค, ๋๋ Redisson ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ ๋์์ฑ ์ ์ด๋ฅผ ๊ตฌํํ๋ค.
ํ ํ๋ก์ ํธ๋ก ์ด์ปค๋จธ์ค ์๋น์ค๋ฅผ ๊ตฌํํ๊ฒ ๋์๋๋ฐ, ์ด์ปค๋จธ์ค์ ํน์ฑ์ ์ฌ๋ฌ ์ฌ์ฉ์๊ฐ ๋์์ ํ ๊ฐ์ง ์ํ์ ๊ตฌ๋งคํ๊ธฐ ์ํ ์์ฒญ์ด ๋ง์ ๊ฒ์ด๊ณ , ์ฌ๋ฌ ์ฌ์ฉ์๊ฐ ๋์์ ํ ๊ฐ์ง์ ์ํ์ ๋ํด ์ฃผ๋ฌธ์ ์์ฑ์ ์์ฒญํ๋ฉด ์๋ชป๋ ํธ๋์ญ์ ์ด ์์ฑ๋ ์ ์๋ค๊ณ ํ๋จํ์๋ค. ์ด๋ฌํ ๋์์ฑ ์ด์๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๋ฐฉ๋ฒ์ ์ฐพ์๋ณด๋ ์ค, ๋ง์นจ ์ธํ๋ผ์ redis๊ฐ ๊ตฌ์ถ๋์ด ์์๊ณ redis์ ์ฌ๋ฌ ๊ธฐ๋ฅ ์ค์ ๋ถ์ฐ ๋ฝ์ ์ ์ฉํ๊ฒ ๋์๋ค.
๐ ๋์์ฑ ์ ์ด ์ ์ฉ ์
- ํ ์คํธ ์๋๋ฆฌ์ค: ์ด๋น 100๋ฒ์ ์์ฒญ์ ํ์ ๋, ์ํ์ ์ฌ๊ณ ๋ 100๊ฐ -> 0๊ฐ, ์ฃผ๋ฌธ์ 100๊ฐ ์์ฑ๋์ด์ผ ํ๋ค.
- ํ ์คํธ ๊ฒฐ๊ณผ: 3์ด ๋์ ์ด 300๋ฒ์ ์์ฒญ์ ํ ๊ฒฐ๊ณผ, ์ํ์ ์ฌ๊ณ ๋ 100๊ฐ-> 0๊ฐ๋ก ์ค์๊ณ , ์ฃผ๋ฌธ์ 107๊ฐ๊ฐ ์์ฑ๋์๋ค.
- ํ ์คํธ ์๋๋ฆฌ์ค: ์ด๋น 100๋ฒ์ ์์ฒญ์ ํ์ ๋, ์ํ์ ์ฌ๊ณ ๋ 1000๊ฐ -> 900๊ฐ, ์ฃผ๋ฌธ์ 100๊ฐ ์์ฑ๋์ด์ผ ํ๋ค.
- ํ ์คํธ ๊ฒฐ๊ณผ: 3์ด ๋์ ์ด 300๋ฒ์ ์์ฒญ์ ํ ๊ฒฐ๊ณผ, ์ํ์ ์ฌ๊ณ ๋ 1000๊ฐ-> 727๊ฐ๋ก ์ค์๊ณ , ์ฃผ๋ฌธ์ 281๊ฐ๊ฐ ์์ฑ๋์๋ค.
์ฌ๋ฌ ๋ฒ์ ์์ฒญ์ ๋ณด๋์ ๋, ๋์์ฑ ์ด์๋ก ์ธํด ์ค์ด๋ ์ํ์ ์ฌ๊ณ ์์ ์ฃผ๋ฌธ์ ์์ฑ ๊ฐ์๊ฐ ๋ง์ง ์๋๋ค. ๋ฐ์ดํฐ์ ์ ํฉ์ฑ์ด ๊นจ์ง ๊ฒ์ด๋ค. ์ด๋ฅผ ๋ถ์ฐ ๋ฝ์ ์ด์ฉํ ๋์์ฑ ์ ์ด๋ฅผ ํตํด ํด๊ฒฐํด ๋ณด๋๋ก ํ์.
๐ Redisson์ ์ด์ฉํ ๋ถ์ฐ ๋ฝ ๊ตฌํํ๊ธฐ
Spring์์ Redisson์ ์ฌ์ฉํ๋ ค๋ฉด build.gradle์ ๋ค์๊ณผ ๊ฐ์ด ์์กด์ฑ์ ์ถ๊ฐํด์ฃผ์ด์ผ ํ๋ค.
dependencies {
// redisson
implementation 'org.redisson:redisson-spring-boot-starter:3.23.2'
}
RedissonClient๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด Redis Config๋ฅผ ์ค์ ํด ์ค๋ค.
@Configuration
@EnableRedisRepositories
public class RedisConfig {
@Value("${spring.data.redis.host}")
private String redisHost;
@Value("${spring.data.redis.port}")
private int redisPort;
private static final String REDISSON_HOST_PREFIX = "redis://";
@Bean
public RedissonClient redissonClient() {
RedissonClient redisson = null;
Config config = new Config();
config.useSingleServer().setAddress(REDISSON_HOST_PREFIX + redisHost + ":" + redisPort);
redisson = Redisson.create(config);
return redisson;
}
@Bean
public RedissonConnectionFactory redisConnectionFactory(RedissonClient redissonClient) {
return new RedissonConnectionFactory(redissonClient);
}
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DistributedLock {
String key(); // ๋ฝ์ ์ด๋ฆ
TimeUnit timeUnit() default TimeUnit.SECONDS; // ๋ฝ์ ์๊ฐ ๋จ์
long waitTime() default 5L; // ๋ฝ์ ๊ธฐ๋ค๋ฆฌ๋ ์๊ฐ
long leaseTime() default 3L; // ๋ฝ ์๋ ์๊ฐ
}
Redisson์ ์ด์ฉํ ๋ก์ง์ ๋ค์๊ณผ ๊ฐ๋ค. ์ด๋ ธํ ์ด์ ์ ์ธ ์ ์ํ๋๋ AOPํด๋์ค์ด๋ค.
@Slf4j
@Aspect
@Component
@RequiredArgsConstructor
public class DistributedLockAop {
private static final String REDISSON_LOCK_PREFIX = "LOCK: ";
private static final long RETRY_DELAY = 3L; // ์ฌ์๋ ์ฌ์ด์ ๋๊ธฐ ์๊ฐ
private static final long MAX_RETRY_COUNT = 5L; // ์ต๋ ์ฌ์๋ ํ์
private final RedissonClient redissonClient;
private final AopForTransaction aopForTransaction;
@Around("...")
public Object lock(final ProceedingJoinPoint joinPoint) throws Throwable {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
DistributedLock distributedLock = method.getAnnotation(DistributedLock.class);
String key = REDISSON_LOCK_PREFIX + CustomSpringELParser.getDynamicValue(
signature.getParameterNames(),
joinPoint.getArgs(),
distributedLock.key());
RLock rLock = redissonClient.getLock(key);
// ๋ฝ ํ๋ ์๋ ๋ฐ ์ฌ์๋ ๋ก์ง
int retryCount = 0;
while (retryCount < MAX_RETRY_COUNT) {
try { // ๋ฝ์ ํ๋ํ๋ ค๊ณ ์๋ํ๊ณ , ์ ์๋ ์๊ฐ์ด ์ง๋๋ฉด ์ ๊ธ์ ํด์ ํ๋ค.
boolean available = rLock.tryLock(distributedLock.waitTime(),
distributedLock.leaseTime(), distributedLock.timeUnit());
if (available) {
System.out.println("Lock acquired with key: " + key);
try {
return aopForTransaction.proceed(joinPoint);
} finally {
if (rLock.isLocked() && rLock.isHeldByCurrentThread()) {
// isLocked(): ํน์ ๋ฝ์ด ํ์ฌ Redis ์๋ฒ์ ๋ฝ ๋์ด ์๋์ง ์ฌ๋ถ๋ฅผ ํ์ธ
// isHeldByCurrentThread(): ํน์ ๋ฝ์ ํ์ฌ ์ค๋ ๋๊ฐ ๋ณด์ ํ๊ณ ์๋์ง ์ฌ๋ถ๋ฅผ ํ์ธ
System.out.println("Lock released with key: " + key);
rLock.unlock();
}
}
} ... {
// ๋ฝ ํ๋ ์คํจ ์ ๋๊ธฐํ๊ณ ์ฌ์๋ํ๋ ๋ก์ง
}
} catch (InterruptedException e) {
log.error("DistributedLock lock interrupted");
System.out.println("DistributedLock lock interrupted");
throw new InterruptedException(e.getMessage());
}
}
throw new IllegalStateException("DistributedLock lock failed after retries");
}
}
๋์์ฑ ํ๊ฒฝ์์์ ๋ฐ์ดํฐ ์ ํฉ์ฑ์ ๋ณด์ฅํ๊ธฐ ์ํด Propagation.REQUIRES_NEW ์ต์ ์ ์ง์ ํ๊ณ , ํธ๋์ญ์ ์ปค๋ฐ ์ดํ์ ๋ฝ์ด ํด์ ๋๊ฒ ์ฒ๋ฆฌํ๋ค.
@Component
public class AopForTransaction {
@Transactional(propagation = Propagation.REQUIRES_NEW)
public Object proceed(final ProceedingJoinPoint joinPoint) throws Throwable {
return joinPoint.proceed();
}
}
๋ถ์ฐ ๋ฝ์ ๊ตฌํํ ์ด๋ ธํ ์ด์ ์ ์ ์ฉํ์ฌ ํ ์คํธ๋ฅผ ์งํํด ๋ณด์.
@Service
@RequiredArgsConstructor
@Component
public class OrderService {
...
@DistributedLock(key = "#orderProducts.![productId].toString()")
public OrderInfo createOrder(
Long memberId,
Long receiverId,
Long totalAmount,
PayType type,
List<OrderProduct> orderProducts
) {
...
OrderEntity saved = orderJpaRepository.save(orderEntity);
historyService.createHistory(saved.getId(), orderProducts);
return ...
}
๐ ๋์์ฑ ์ ์ด ์ ์ฉ ํ
- ํ ์คํธ ์๋๋ฆฌ์ค: ์ด๋น 100๋ฒ์ ์์ฒญ์ ํ์ ๋, ์ํ์ ์ฌ๊ณ ๋ 100๊ฐ -> 0๊ฐ, ์ฃผ๋ฌธ์ 100๊ฐ ์์ฑ๋์ด์ผ ํ๋ค.
- ํ ์คํธ ๊ฒฐ๊ณผ: 3์ด ๋์ ์ด 300๋ฒ์ ์์ฒญ์ ํ ๊ฒฐ๊ณผ, ์ํ์ ์ฌ๊ณ ๋ 100๊ฐ-> 0๊ฐ๋ก ์ค์๊ณ , ์ฃผ๋ฌธ์ 100๊ฐ๊ฐ ์์ฑ๋์๋ค.
- ํ ์คํธ ์๋๋ฆฌ์ค: ์ด๋น 100๋ฒ์ ์์ฒญ์ ํ์ ๋, ์ฌ๊ณ 1000๊ฐ -> 900๊ฐ, ์ฃผ๋ฌธ์ 100๊ฐ ์์ฑ๋์ด์ผ ํ๋ค.
- ํ ์คํธ ๊ฒฐ๊ณผ: 3์ด ๋์ ์ด 300๋ฒ์ ์์ฒญ์ ํ ๊ฒฐ๊ณผ, ์ฌ๊ณ ๋ 1000๊ฐ -> 700๊ฐ, ์ฃผ๋ฌธ์ 300๊ฐ๊ฐ ์์ฑ๋์๋ค.
์ฌ๊ธฐ๊น์ง ๋์์ฑ ์ด์๊ฐ ์ผ์ด๋ฌ์ ๋ Redisson์ ์ฌ์ฉํ ๋ถ์ฐ ๋ฝ์ ๊ตฌํ์ ๋ํด ์์๋ณด์๋ค.
๐ ์ฐธ๊ณ
ํํ๋จผํธ ์ ๊ณ ์๋น์คํ์์ ๋ถ์ฐ๋ฝ์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ - Spring Redisson
์ด๋ ธํ ์ด์ ๊ธฐ๋ฐ์ผ๋ก ๋ถ์ฐ๋ฝ์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ๋ํด ์๊ฐํฉ๋๋ค.
helloworld.kurly.com
๋ ๋์ค์ ๋ถ์ฐ ๋ฝ(1/2) - ๋ ๋์ค๋ฅผ ํ์ฉํ ๋ถ์ฐ ๋ฝ๊ณผ ์์ ํ๊ณ ๋น ๋ฅธ ๋ฝ์ ๊ตฌํ
๋ ๋์ค๋ฅผ ํ์ฉํ ๋ถ์ฐ ๋ฝ์ ๋ํด ์์๋ด ๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ฑ๋ฅ์ ๋์ด๊ณ ์ผ๊ด์ฑ์ ๋ณด์ฅํ๋ ๋ฐฉ๋ฒ์ ๋ํด ์์๋ด ๋๋ค.
hyperconnect.github.io
[Redis] ๋ถ์ฐ ๋ฝ (feat. Redisson)
๋ถ์ฐ ๋ฝ์ด๋? ๋ถ์ฐ ๋ฝ(Distributed Lock)์ ๋ค์์ ์๋ฒ(๋๋ ํ๋ก์ธ์ค)๊ฐ ๋์์ ๊ฐ์ ์์์ ์ ๊ทผํ ๋ ๋ฐ์ํ ์ ์๋ ๋์์ฑ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ์ฌ์ฉ๋๋ ๋๊ธฐํ ๋ฉ์ปค๋์ฆ์ ๋๋ค. ๋ถ์ฐ ๋ฝ์ ํต
inma.tistory.com
8. Distributed locks and synchronizers
Redisson - Valkey and Redis Java client. Complete Real-Time Data Platform. Sync/Async/RxJava/Reactive API. Over 50 Valkey and Redis based Java objects and services: Set, Multimap, SortedSet, Map, L...
github.com