๐ค ์๋ก ์ด๋ฒ ๊ธ์์๋ Redis๋ฅผ ์ฌ์ฉํ์ฌ ๋ถ์ฐ๋ฝ์ ๊ตฌํํด ๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค. Java์ Redis ํด๋ผ์ด์ธํธ๋ก๋ Jedis, Lettuce, Redisson ๋ฑ์ด ์์ผ๋ฉฐ, ๊ฐ๊ฐ์ ํน์ง์ด ์๋ก ๋ค๋ฆ
๋๋ค. ์ด์ค์์ Jedis๋ ์ ์ธํ๊ณ Lettuce์ Redisson์ ์ฌ์ฉํด์ ๋ถ์ฐ๋ฝ์ ๊ตฌํํด ๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค. (Jedis์ Lettuce์ ๋น๊ต๋ ๋ค์ ๊ธ์ ์ฐธ๊ณ ํด์ฃผ์ธ์) ๐ค Redis ํ๊ฒฝ ์ค์ ์๋ ๋ช
๋ น์ด๋ฅผ ํตํด redis๋ฅผ ๋ค์ด๋ฐ์์ค๋๋ค. (๋ฐ๋์ ๋์ปค๋ฅผ ์ฌ์ฉํ ํ์๋ ์์ต๋๋ค.) docker pull redis ์ดํ ๋ ๋์ค๋ฅผ ์คํ์์ผ์ค๋๋ค. docker run --name redis -d -p 6379:6379 redis ํ๋ก์ ํธ์์๋ Redis ๊ด๋ จ ์์กด์ฑ์ ์ถ๊ฐํด์ฃผ๋๋ก ํ๊ฒ ์ต๋๋ค. imple..
๐๏ธ Spring
๐ค ์๋ก ์ด์ ๊ธ์์๋ ๋น๊ด์ ๋ฝ(Pessimistic Lock)๊ณผ ๋๊ด์ ๋ฝ(Optimistic Lock)์ ํตํด ๋ถ์ฐ๋ฝ์ ๊ตฌํํ์ฌ ๋จ์ผ ์๋ฒ๋ ๋ฌผ๋ก ๋ค์ค ์๋ฒ์์๋ ๋์์ฑ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ์์ต๋๋ค.์ด๋ฒ ๊ธ์์๋ ๋น๊ด์ ๋ฝ๊ณผ ๋น์ทํ MySQL์ USER-LEVEL Lock(Named Lock)์ ํตํด์ ๋์์ฑ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํด ๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.(์์ผ๋ก๋ user-level lock์ด๋ผ๊ณ ๋ถ๋ฅด๋๋ก ํ๊ฒ ์ต๋๋ค.) ๐ค USER-LEVEL Lock (Named Lock)MySQL ๊ณต์ ๋ฌธ์๋ฅผ ๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ์ user level lock์ ์ง์ํด์ฃผ๋ ๊ฒ์ ์ ์ ์์ต๋๋ค. ๐ณ GET_LOCK(str, timeout)์ฃผ์ด์ง ์ด๋ฆ(str)์ ๋ํ Lock ํ๋์ ์๋ํฉ๋๋ค. ์ด๋ ๋ฌธ์์ด์ ๊ธธ์ด๋ ์ต๋..
๐ค ์๋ก ์ด์ ๊ธ์์ ์์๋ณธ synchronized๋ ๋จ์ผ ์๋ฒ ํ๊ฒฝ์์๋ง ๋์์ฑ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์์์ต๋๋ค. ์ด๋ฒ ๊ธ์์๋ ๋ค์ค ์๋ฒ ํ๊ฒฝ์์ ๋์์ฑ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๋ ๋ฐฉ๋ฒ์ ๋ํด ์์๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค. ์ฌ๋ฌ ๋์ ์๋ฒ์์ ๋์ผ ์์์ ์ ๊ทผํ๋ ๊ฒฝ์ฐ, ๋์์ ํ ๊ฐ์ ํ๋ก์ธ์ค(ํน์ ์ฐ๋ ๋)๋ง ์ ๊ทผ ๊ฐ๋ฅํ๋๋ก ํ๊ธฐ ์ํด ์ฌ์ฉํ๋ Lock์ ๋ถ์ฐ ๋ฝ(Distributed Lock)์ด๋ผ ๋ถ๋ฆ
๋๋ค. ์ด์ ๋ถํฐ ๋ถ์ฐ ๋ฝ์ ๊ตฌํํ๋ ์ฌ๋ฌ ๋ฐฉ๋ฒ๋ค์ ๋ํด ์์๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค. ๐ก ๋ถ์ฐ ๋ฝ์ ๋ํด์ ๋ถ์ฐ ๋ฝ์ ๋ํด์ ์ด๋ ๋ค ํ ์์ ํ ์ ์๋ฅผ ์ฐพ์ง๋ ๋ชปํด์ ๋ค์ ๋ ์ํฉ์ด ํผ๋๋ ์ ์์ ๊ฒ ๊ฐ์ต๋๋ค. 1. ์น ์ ํ๋ฆฌ์ผ์ด์
์๋ฒ๊ฐ ์ฌ๋ฌ๋์ธ ๊ฒฝ์ฐ, ์ด๋ค๊ฐ์ ๋์์ฑ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ์ฌ์ฉ๋๋ Lock 2. ์ค์ผ์ผ..
๐ค ์๋ก ๋ค์ค ์ฌ์ฉ์๋ฅผ ์ํ ์น ์ ํ๋ฆฌ์ผ์ด์
์ ๋ง๋ค๋ค ๋ณด๋ฉด ํ ๋ฒ์ฏค์ ๋์์ฑ ๋ฌธ์ ์ ์ ํ๊ฒ ๋ฉ๋๋ค. ๋์์ฑ ๋ฌธ์ ๋ ํ๋์ ์์์ ๋ํด์ ์ฌ๋ฌ ์ฐ๋ ๋๊ฐ ๋์์ ์ ๊ทผํ์ฌ ์์ ํ๋ ๊ฒฝ์ฐ์ ๋ฐ์ํ๋ ๋ฌธ์ ์
๋๋ค. ๋์์ฑ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ ๊ฐ๋จํ ์์๋ก๋ ํน์ ๊ฒ์๋ฌผ์ ์กฐํ ์๊ฐ ์ฌ๋ฐ๋ฅด๊ฒ ์ฆ๊ฐ๋์ง ์๋ ๋ฌธ์ ๊ฐ ์์ ์ ์์ต๋๋ค. ํน์ ๊ฒ์๋ฌผ์ 100๋ช
์ ์ฌ์ฉ์๊ฐ ๋์์ ์ ๊ทผํ๋ ๊ฒฝ์ฐ ์กฐํ์๋ 100์ด ๋์ด์ผ ์ณ๊ฒ ์ง๋ง, ๋๋ถ๋ถ์ ๊ฒฝ์ฐ ์กฐํ์๋ 100๋ณด๋ค ์์ ๊ฐ์ผ๋ก ์ค์ ๋ ๊ฒ์
๋๋ค. ์กฐํ์ ๊ฐ์ ๊ฒฝ์ฐ์๋ ๋์ฒด๋ก ๋ฐ์ดํฐ์ ์ ํฉ์ฑ์ด ์ค์ํ์ง ์๊ธฐ ๋๋ฌธ์ ์ด๋ฌํ ๋ถ๋ถ์ด ๋ฌธ์ ๊ฐ ๋์ง ์์ ์ ์์ง๋ง, ์ํ์ ์ฌ๊ณ ์๋๊ณผ ๊ฐ์ ๊ฒฝ์ฐ์ ์ด๋ฌํ ๋์์ฑ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค๋ฉด ์น๋ช
์ ์ผ ์ ์์ต๋๋ค. ์ด๋ฌํ ๋์์ฑ ๋ฌธ์ ๋ฅผ ๋ง๊ธฐ ์ํด์๋ ๋ค..
(์ ๊ถ๊ธ์ฆ ํ ์ฉ๋๋ก ์ ๋ฆฌํ๊ฑฐ๋ผ ๋ง ๊น๋ํ๊ฒ ์ ๋ฆฌํ์ง๋ ์์์ต๋๋ค.) ๐ง ManyToOne, OneToOne ์ฐ๊ด๊ด๊ณ ์ผ๋ฐ์ ์ผ๋ก merge ์ merge๋๋ ํน์ ์ํฐํฐ์ ๋ํด์๋ง ์กฐํํฉ๋๋ค. ๊ทธ๋ฌ๋ cascade ์์ฑ์ด MERGE๋ผ๋ฉด merge ์ ์ฐ๊ด๋ ์ํฐํฐ๋ค๋ left join์ผ๋ก ์กฐํํด์ต๋๋ค. merge()๊ฐ ๋์ด ๊ฐ์ด ๋ณ๊ฒฝ๋๋ ๊ฒ๋ ์ผ๋ฐ์ ์ผ๋ก๋ fk ๊ฐ์ ๋ณ๊ฒฝ๋ง์ด ๋ฐ์๋์ง๋ง, cascade ์์ฑ์ด merge๋ผ๋ฉด ์ฐ๊ด๋ ์ํฐํฐ์ ๋ณ๊ฒฝ๋ ํจ๊ป ๋ฐ์๋ฉ๋๋ค. (DB ๊ด์ ์์ ์๊ฐํ๋ฉด ํธํฉ๋๋ค) @NoArgsConstructor @Accessors(fluent = true) @Getter @Entity public class Member { @Id @GeneratedValue(strategy = Ge..
๐ง ๋ฌธ์ ์ํฉ @Service @Transactional @RequiredArgsConstructor public class PostService { private final PostRepository postRepository; private final MemberRepository memberRepository; public Long create(CreatePostCommand command) { Member member = memberRepository.findById(command.memberId()) .orElseThrow(NotFoundMemberException::new); Post post = command.toPost(member); Post saved = postRepository.sa..
(์ ์์ ๋ฐฑ์๋ ๊ฐ๋ฐ์๊ธฐ ๋๋ฌธ์ React๋ ๋ชปํฉ๋๋ค. React ์ฝ๋๋ Chat GPT ์์ผ์ ๊ตฌํํ์๊ณ , ๋์ ๋ฐฑ์๋์ ์จ ์ง์ฌ์ ๋ดํ์ ๊ตฌํํ์์ผ๋, ํ๋ก ํธ ์ฝ๋๋ ์ ๋ง ๊ทธ๋ฅ ํ
์คํธ์ฉ์ผ๋ก๋ง ์ฐธ๊ณ ํด ์ฃผ์๋ฉด ๊ฐ์ฌํ๊ฒ ์ต๋๋ค.) OAuth์ ๊ฐ๋
์ ๋ํด์๋ ์ด๋ฏธ ๋ง์ ๋ธ๋ก๊ทธ๋ค์์ ๋ค๋ฃจ๊ณ ์์ผ๋ฏ๋ก ์ ๋ ์ด์ ๋ํด์๋ ๋ฐ๋ก ๋ค๋ฃจ์ง ์๊ฒ ์ต๋๋ค. ์ด ๊ธ์์๋ (์ ์ด๋ ์ ๊ฐ ์ดํด๋ณด์๋) ๋๋ถ๋ถ์ ๋ธ๋ก๊ทธ์์ ์ ๋งคํ๊ฒ ์ค๋ช
๋์ด์๋ ํ๋ก ํธ์๋์ ๋ฐฑ์๋์ ์ญํ ๊ณผ, ์ค์ ๋ก ์ด๋ป๊ฒ ๊ตฌํํ๋์ง๋ฅผ ์ง์ค์ ์ผ๋ก ๋ค๋ค๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค. ๋ํ ์ด ๊ณผ์ ์์ ๋จ์ํ ๊ตฌํํ๊ณ ๋๋ด๋ ๊ฒ์ด ์๋๋ผ ์๋ก์ด ํ์ฌ ํ๋ซํผ์ ์ถ๊ฐํ๋ ๊ณผ์ ๋ ๊ฐ๋จํ๊ฒ ์ฒ๋ฆฌํ ์ ์๋๋ก ์ ์ฐํ๊ณ ํ์ฅ ๊ฐ๋ฅํ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ ธ๊ฐ๋ ์ฝ๋๋ฅผ ์์ฑํด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค. ์์ค ์ฝ๋๋..
๐ง ์ธ์ํ
์คํธ ๋ฐ์ดํฐ ์ด๊ธฐํ ์ธ์ํ
์คํธ ํน์ ํตํฉํ
์คํธ๋ฅผ ์์ฑํ ๋์๋ ํ
์คํธ๋ฅผ ๊ฒฉ๋ฆฌํ๊ธฐ ์ํด ๋ค์ํ ๋ฐฉ์์ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ด์ ๊ด๋ จํ ์ฌ๋ฌ ๋ฐฉ๋ฒ์ ๋ํด์๋ ์ธ์ํ
์คํธ์์ ํ
์คํธ ๊ฒฉ๋ฆฌํ๊ธฐ ๊ธ์ ์์ธํ ๋ํ๋ ์์ต๋๋ค. ์ ๋ ์ฌ๋ฌ๊ฐ์ง ๋ฐฉ๋ฒ๋ค ์ค @Sql ์ ๋
ธํ
์ด์
์ ์ฌ์ฉํ์ฌ truncate ์ฟผ๋ฆฌ๋ฅผ ์์ฑํ๋ ๋ฐฉ๋ฒ์ ์ฃผ๋ก ์ฌ์ฉํ์๋๋ฐ์, ์ด ๋ฐฉ๋ฒ์ truncate.sql ํ์ผ์ ์ฝ๋๊ฐ ์์กด์ ์ด๊ฒ ๋๋ฉฐ, ํ
์ด๋ธ์ด ์๋ก ์ถ๊ฐ๋๊ฑฐ๋ ์ญ์ ๋๋ ๊ฒฝ์ฐ truncate.sql ํ์ผ๋ ๊ณ์ํด์ ์์ ํด์ฃผ์ด์ผ ํ๋ค๋ ๋จ์ ์ ๋๊ผ์ต๋๋ค. ๊ทธ๋ฌ๋ ์ค BeforeEachCallback๋ผ๋ ๊ฒ์ ๋ํด ์๊ฒ๋์๊ณ , ์ด๋ฅผ ์ฌ์ฉํ์ฌ truncate.sql ํ์ผ ์์ด๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ด๊ธฐํ๋ฅผ ์๋ํ ์์ผฐ๋๋ฐ์, ํด๋น ๋ฐฉ๋ฒ์ ๋ํด์ ์..