1. ๊ฐ์
ํ์ฌ ์งํ์ค์ธ ์ฐฝ์ ํ๋ก์ ํธ์ ๊ธฐ๋ฅ ๊ฐ๋ฐ์ด ๋๋ถ๋ถ ๋๋๊ณ , ์ฌ์ ์๊ฐ ๋์์ผ ํ ์ ์๋ SMS, ์๋ฆผํก ๋ถ๋ถ๊ณผ ๋ฑ ํน ๊ธฐ๋ฅ๋ง์ด ๋จ์๋ค.
์ง๋ 5๊ฐ์๊ฐ ์ ์ ์์ด ๊ธฐ๋ฅ ๊ฐ๋ฐ์ ์ง์คํ๋ค๋ณด๋ ๋ฏธํกํ ๋ถ๋ถ์ด ๊ฝค๋ ๋ณด์๊ณ ์ต๊ทผ์ ํ๋ํ๋ ๋ฆฌํํฐ๋ง ๊ณผ์ ์ ๋ฐ๊ณ ์๋ค.
๊ผผ๊ผผํ ์ง๋ ์ฝ๋๋ฅผ ์ดํผ๋ ์ค ๋์์ฑ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ๋งํ ๋ก์ง์ด ๋ฐ๊ฒฌ๋๊ณ ์ด๋ฅผ ํด๊ฒฐํ๊ณ ์ Thread-Safe, ๋์์ฑ ๋ฌธ์ ์ ๋ํด ๊ณต๋ถํ๊ฒ ๋๋ค.
์๋ ๊ฒ์๊ธ์์ ๊ณต๋ถํ๋ ๋ด์ฉ๋ค์ ์ ๋ฆฌํด๋๋ค.
https://dgjinsu.tistory.com/53
https://dgjinsu.tistory.com/54
ํ์ง๋ง ๋ด ์ฝ๋์ ๋์์ฑ ๋ฌธ์ ๋ ์ผ๋ฐ์ ์ผ๋ก ๋์์ฑ ๋ฌธ์ ๋ก ๋ค๋ฃจ๋ ์ํฉ๋ค๊ณผ๋ ์กฐ๊ธ์ ๋ฌ๋๋ค.
2. ๋ฌธ์ ์ํฉ
์ ์ฌ์ง์ ๋ด ์ฝ๋์์ ๋์์ฑ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ ์ํฉ์ ์กฐ๊ธ์ด๋๋ง ์ดํดํ๊ธฐ ์ฝ๋๋ก ๊ทธ๋ฆฐ ์ฌ์ง์ด๋ค.
๋ฌธ์ ์ํฉ์ ๊ธ๋ก๋ ํํํ๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
๊ฐ๋ฐ ์๊ตฌ ์ฌํญ
๊ฐ์ ๋ ์ง์ ๋ ธ๋์๋ ๋ ๊ฐ์ ์ผ์ ํ ์ ์๋ค. ์ฆ, ํ ๊ฐ ์ด์์ status ๊ฐ accepted์ธ Apply(์ง์) ์ด ์์ผ๋ฉด ์ ๋จ.
๋ ธ๋์๋ ์ผ์๋ฆฌ ๊ณต๊ณ ์ ์ง์(Apply)ํ ์ ์๊ณ ๊ธฐ์ ์ด ํด๋น ๋ ธ๋์์ ์ง์(Apply)๋ฅผ ์๋ฝํด์ผ ํ์ ์ด ๋๋ค. ์๋ฝ ์ ์ ์ง์(Apply)์ status๋ pending์ด๋ค.
์๋ฝ์ ํ๋ฉด ์ง์(Apply)์ status ํ๋๋ accepted๋ก ๋ณ๊ฒฝ๋๋ค.
๋ ธ๋์๋ ๊ธฐ์ ์ผ๋ก๋ถํฐ ์ผ์๋ฆฌ๋ฅผ ์ ์(Offer) ๋ฐ์ ์ ์๋ค. ์ ์(Offer)์ ๋ ธ๋์๊ฐ ์๋ฝํ๋ฉด ๋ฐ๋ก ์ผ์๋ฆฌ๊ฐ ํ์ ๋๋ค. ๋ ธ๋์๊ฐ ์ ์(Offer)๋ฅผ ์๋ฝํ๋ฉด status ๊ฐ accepted์ธ Apply(์ง์) ์ ์์ฑํ๋ค.
๊ทธ๋ ๋ค๋ฉด ๊ธฐ์ ์ด ๋ ธ๋์A์ ์ง์์ ์๋ฝํ๋ ๋์์, ๋ ธ๋์A๊ฐ ์ ์๋ฐ์ ์ผ์๋ฆฌ๋ฅผ ์๋ฝํ๋ค๋ฉด status ๊ฐ accepted์ธ Apply(์ง์) ์ด ๋ ๊ฐ ์๊ธฐ๊ฒ ๋๋ค.
๋ฐ๋ก ์ฌ๊ธฐ์ ๋์์ฑ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ ๊ฒ์ด๋ค.
๊ทธ๋ ๋ค๋ฉด ์์์ ์ผ๋ฐ์ ์ธ ๋์์ฑ ์ํฉ๊ณผ๋ ๋ค๋ฅด๋ค๊ณ ํ ์ด์ ๋ ๋ญ๊น?
์ผ๋ฐ์ ์ธ ๋์์ฑ ๋ฌธ์ ์์ ํ๋์ ๊ณต์ ์์์ ์์ ํ ๋๋ฅผ ๋ง์ด ๋ค๋ฃฌ๋ค. ์ด๋ฐ ๊ฒฝ์ฐ ๋ฝ์ ๊ฑธ์ด ํด๊ฒฐํ์ง๋ง, ๋๋ Apply(์ง์)์ ์๋ก ์์ฑํ๊ธฐ ๋๋ฌธ์ ๋ฝ์ ๊ฑธ๊ธฐ์ ์ ๋งคํ๋ค.
3. ํด๊ฒฐ ๋ฐฉ์
์ฒ์ ๋ ์ฌ๋ฆฐ ๋ฐฉ์์ ๋ฉ์ ์ ํ ๊ฐ์ ํ ์๋น์ค๋ฅผ ์ฌ์ฉํด์ ๋ ์๋ํฌ์ธํธ์ ๋ํ ์ฒ๋ฆฌ๋ฅผ ๋ณ๋ ฌ๋ก ์ฒ๋ฆฌํ์ง ์๋๋ก ํ๋ ๋ฐฉ์์ ๋ ์ฌ๋ ธ๋ค.
์นดํ์นด ๊ฐ์ ๊ธฐ์ ์ ๋์ ํ๊ธฐ์ ์์ง ๋ถ๋ด์ค๋ฌ์ ๊ณ , ๋ค๋ฅธ ๋ฐฉ๋ฒ์ ์ฐพ๋ค ๋ฝ์ ๊ฑธ ์ ์๋ ์ํฉ์ผ๋ก ๋ก์ง ์ค๊ณ๋ฅผ ๋ฐ๊ฟ๋ณด๊ธฐ๋ก ํ๋ค.
Apply(์ง์) ๋ฐ์ดํฐ๋ฅผ ์๋ก ์์ฑํ๊ธฐ ๋๋ฌธ์ ๋ฝ์ด ๊ฑธ๊ธฐ ํ๋ค์์ผ๋, Offer(์ ์)ํ ๋ Apply(์ง์) ๋ฐ์ดํฐ๊น์ง ๋ฏธ๋ฆฌ ๋ฃ์ด๋๋ฉด ๋ฝ์ ๊ฑธ์ด ๋์์ฑ์ ์๋ฐฉํ ์ ์์๊ฑฐ๋ผ ์๊ฐํ๋ค.
๋์์ฑ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํด์ผํ๋ ์ฝ๋์ด๋ค.
public void processOffer(Long workerId, OfferProcessRequest request) {
// ์๋ต
// ์์ฒญ์ ๋ฐ๋ผ Apply ์ญ์ or status ์
๋ฐ์ดํธ
Apply offeredApply = applyRepository.findOfferedApply(worker.getId(), workDate.getId())
.orElseThrow(() -> new CustomException(ErrorCode.APPLY_OFFERED_NOT_FOUND));
// ์๋ฝ์ผ ๋
if (request.getIsAccept()) {
// ์๋ต
// ๋ชจ์ง๋ ์ธ์ ์ฆ๊ฐ
workDate.plusRegisteredNum(1);
// ์ ์ ๋ฐ์ผ๋ฉฐ ์๋์ผ๋ก ์๊ธด ์ง์ ๊ธฐ๋ก ์น์ธ ์ฒ๋ฆฌ
offeredApply.updateStatus(ApplyStatus.ACCEPTED, LocalDateTime.now());
//์๋ต
}
// ๊ฑฐ์ ์ผ ๋
else {
// ์ ์ ๋ฐ์ผ๋ฉฐ ์๋์ผ๋ก ์๊ธด ์ง์ ๊ธฐ๋ก ์ ๊ฑฐ
applyRepository.delete(offeredApply);
}
// ์๋ต
}
์ ์ฝ๋์์ ์กฐํํ offerdApply์ status๋ฅผ ์ ๋ฐ์ดํธ ํ๋ ์ค, ๊ธฐ์ ์ด ๋ค๋ฅธ Apply(์ ์)์ ๊ธฐ์ ์ด ์๋ฝํด๋ฒ๋ฆฌ๋ฉด ๋์์ฑ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค.
ํด๊ฒฐ์ ์ํด ๋น๊ด์ Lock์ ์ฌ์ฉํ์ฌ member์ Apply ๋ฐ์ดํฐ ์ ๋ถ์ Lock์ ๊ฑธ์ด์ฃผ์๋ค.
public void processOffer(Long workerId, OfferProcessRequest request) {
// ์๋ต
// ๋์์ฑ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํ Lock ์ฟผ๋ฆฌ
applyRepository.findWorkerApplyForLock(worker.getId());
// ์์ฒญ์ ๋ฐ๋ผ Apply ์ญ์ or status ์
๋ฐ์ดํธ
Apply offeredApply = applyRepository.findOfferedApply(worker.getId(), workDate.getId())
.orElseThrow(() -> new CustomException(ErrorCode.APPLY_OFFERED_NOT_FOUND));
// ์๋ฝ์ผ ๋
if (request.getIsAccept()) {
// ์๋ต
// ๋ชจ์ง๋ ์ธ์ ์ฆ๊ฐ
workDate.plusRegisteredNum(1);
// ์ ์ ๋ฐ์ผ๋ฉฐ ์๋์ผ๋ก ์๊ธด ์ง์ ๊ธฐ๋ก ์น์ธ ์ฒ๋ฆฌ
offeredApply.updateStatus(ApplyStatus.ACCEPTED, LocalDateTime.now());
//์๋ต
}
// ๊ฑฐ์ ์ผ ๋
else {
// ์ ์ ๋ฐ์ผ๋ฉฐ ์๋์ผ๋ก ์๊ธด ์ง์ ๊ธฐ๋ก ์ ๊ฑฐ
applyRepository.delete(offeredApply);
}
// ์๋ต
}
Repository ์ฝ๋์ด๋ค.
@Lock(LockModeType.PESSIMISTIC_WRITE)
@Query("select a from Apply a where a.member.id = :memberId")
List<Apply> findWorkerApplyForLock(@Param("memberId") Long memberId);
์์ ๊ฐ์ด @Lock์ ๋ถ์ฌ์ค์ผ๋ก์จ ๋ค์๊ณผ ๊ฐ์ด ์ฟผ๋ฆฌ๊ฐ ๋๊ฐ๋ค.
๋น๊ด์ Lock์ ๊ฑด ๊ฒฝ์ฐ select ~ for update ์ฟผ๋ฆฌ๊ฐ ๋๊ฐ๋ค. ์ฆ, ์ฌ๊ธฐ์ ์กฐํ๋ ๋ ์ฝ๋๋ Lock์ด ๊ฑธ๋ฆฐ๋ค.
4. ๊ฒฐ๋ก
๋์์ฑ ๋ฌธ์ ๋ ์์๊ณผ ๋ค๋ฅด๊ฒ ๋ฐ์ดํฐ๊ฐ ์ฒ๋ฆฌ๋ ์ ์๊ธฐ ๋๋ฌธ์ ์กฐ์ฌํด์ ๊ฐ๋ฐํด์ผ ํ๋ค. ๋๊ฐ์ ๊ฒฝ์ฐ์๋ ์ง์ ํ์ ์ด ๋ ๊ฐ ๋๋ฒ๋ฆฌ๋ฉด ๊ธฐ์ ๋ฟ๋ง ์๋๋ผ ๋ ธ๋์์๊ฒ๋ ํ๊ฒฉ์ด ๊ฐ๋ ์ํฉ์ด๊ธฐ ๋๋ฌธ์ ๋๋ฌผ์ง๋ง ๊ทธ๋ฐ ์ผ์ด ์ผ์ด๋์ง ์๋๋ก ๋ฐฉ์งํด์ผํ๋ค.
์์์ ๋ค๋ฃฌ ์ํฉ ๋ง๊ณ ๋ ํ์ฌ ํ๋ก์ ํธ์ ๋์์ฑ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํด์ผ ํ๋ ๋ช ๊ฐ์ง ๋ก์ง๋ค์ด ๋ ์กด์ฌํ๋ค. ํ์ ์์ ์ด๋ณด๋ค ์๋ง์ ์์์น ๋ชปํ ๋ฌธ์ ๋ค์ด ๋ง์ด ๋ฐ์ํ ํ ๋ฐ ๋นจ๋ฆฌ ๊ฒฝํํด๋ณด๊ณ ์ถ๋ค..ใ