๋ชฉ์ฐจ
์ํฉ
1. ์ด๋ฒคํธ์ ๋น์ฒจ๋ ๊ฒฝ์ฐ ํด๋ํฐ๋ฒํธ๋ฅผ ์ ๋ ฅํ๊ณ [์ฟ ํฐ๋ฐ๊ธฐ] ๋ฒํผ์ ๋๋ฅด๋ฉด ์ฟ ํฐ์ด ์ฆ์ ๋ฐ์ก๋๋ค.
2. ๊ทผ๋ฐ ๊ฐ๋์ฉ [์ฟ ํฐ๋ฐ๊ธฐ] ๋ฒํผ์ด ๋๋ฆฐ์ฑ๋ก ์๋ฌด๋ฐ ๋ฐ์์ด ์๋ ๊ฒฝ์ฐ๊ฐ ์๋ค.
(๋ธ๋ผ์ฐ์ ์์ฒด๊ฐ ๋ฉ์ถ๋ค๋๊ฐ... ์๋ฌด๋ฐ ์ก์ ์์ด ๊ทธ๋ฅ ๋๊ธฐ๋ง ํ๋ค๋๊ฐ...)
3. ๊ธฐ๋ค๋ ค๋ ์๋ต์ด ์์ผ๋ ์ฌ๋๋ค์ [์ฟ ํฐ ์๋ฐ๊ธฐ] ๋ฒํผ์ ๋๋ฅธ๋ค.
4. [์ฟ ํฐ ์๋ฐ๊ธฐ] ๋ฒํผ์ ๋๋ฅด๋ฉด ๋น์ฒจ๋ด์ญ์ ์ด๊ธฐํ์ํจ๋ค. (๋ค๋ฅธ์ฌ๋์๊ฒ ํ ๋น๋์ด์ผํ๋ฏ๋ก)
์๋ฒ์ ์ฐํ ๋ก๊ทธ๋ ์๋์ ๊ฐ๋ค.
2022-12-05 10:45:24 ์ฟ ํฐ๋ฐ๊ธฐ ์์
2022-12-05 10:45:25 ์ฟ ํฐ์๋ฐ๊ธฐ ์์
2022-12-05 10:45:25 ์ฟ ํฐ๋ฐ๊ธฐ-์ฟ ํฐ๋ฐ์ก ์ฑ๊ณต
2022-12-05 10:45:26 ์ฟ ํฐ์๋ฐ๊ธฐ ์ข
๋ฃ
2022-12-05 10:45:27 ์ฟ ํฐ๋ฐ๊ธฐ ์ข
๋ฃ << Error!!!
UnexpectedRollbackException: Transaction silently rolled back
because it has been marked as rollback-only....
์ผ๋จ ์ฟ ํฐ์ด ๋ฐ์ก๋์๊ณ
DB์ ํด๋ํฐ๋ฒํธ์ ๋น์ฒจ๋ด์ญ์ ๋ณด๋ ๋กค๋ฐฑ๋์ด ๋ฐ์ดํฐ๊ฐ ๋ ์๊ฐ ์ํฉ์ด์๋ค
ใ ใทใท...... ์์ ์ด๋ฒคํธ ๋ฏธ์ฐธ์ฌํ ๊ณ ๊ฐ์ผ๋ก ๋์ด....
๋ ๊ณ ๋ คํด์ผํ ์ ์ ์์์ฒ๋ผ [์ฟ ํฐ์๋ฐ๊ธฐ] ์ข ๋ฃ ์ดํ [์ฟ ํฐ๋ฐ๊ธฐ] ์ข ๋ฃ๋ก ์์๊ฐ ๊ณ ์ ๋์ด์์ง ์๊ณ
์ด๋ค๊ฒ ๋จผ์ ์ํ๋ ์ง ๋ชจ๋ฅธ๋ค๋ ์ ...
์๋ํ ๊ฒ
Jpa & Querydsl Lock ์ค์
//jpa
@Lock(value = LockModeType.PESSIMISTIC_WRITE)
//querydsl
query.setLockMode(LockModeType.PESSIMISTIC_WRITE);
[์ฟ ํฐ๋ฐ๊ธฐ]์ [์ฟ ํฐ์๋ฐ๊ธฐ] ์์ id(15๋ฒ)๋ก ์กฐํํ ๋
๋น๊ด์ ๋ฝ์ ์ ์ฉํ์ฌ ๋ค๋ฅธ ํธ๋์ญ์ ์์ ์ฝ๊ธฐ๋ ์ฐ์ง๋ ๋ชปํ๊ฒ ํ์๋ค.
select๋ฌธ ๋ค์ for update๊ฐ ๋ถ๋ ๊ฒ์ ํ์ธํ์๋๋ฐ... ์กฐํ๊ฐ ๋๋ค..!
PESSIMISTIC_WRITE๋ ๋ถ๋ช ์ฝ๊ธฐ๋ ์ฐ์ง๋ ๋ชปํ๋ค๊ทธ๋ฌ๋๋ฐ... ์กฐํ๊ฐ๋๋ค......
๋ด๊ฐ ํ ์คํธ๋ฅผ ์๋ชปํ๊ฒ์ผ์๋ ์์ง๋ง.. ๋ค๋ฅธ๋ถ๋ค๋ ๋ช๋ฒ ํ ์คํธ ํด๋ดค์ง๋ง ์กฐํ๊ฐ ๋์๊ณ ,
update๋ฌธ์ด ๋๊ฐ๋ ๋๊ฐ์ด ์๋ฌ๊ฐ ๋ฐ์ํ๋ฉฐ ๋กค๋ฐฑ๋์ด์ ์ด ๋ฐฉ๋ฒ์ ์คํจ
๋์ ํด๊ฒฐ๋ฐฉ๋ฒ
update ~~ where ~~ ์กฐ๊ฑด ์ค์
์๋ฒ์์ ๋ฐ์ดํฐ๋ฅผ ์ฒดํฌํด์ ์ ์ดํ๊ธฐ์ ์ข ์ด๋ ต๋ค๊ณ ์๊ฐ๋์ด์ Query๋ก ํด๊ฒฐํ๊ธฐ๋ก ํ๋ค!
์ด์ฐจํผ DB์์ update๋ฌธ์ 1๋ฒ์ 1๊ฐ๋ง ์ํ๋ ๊ฒ์ด๋ค.
[์ฟ ํฐ ๋ฐ๊ธฐ], [์ฟ ํฐ ์๋ฐ๊ธฐ] ์์ ์กฐํํ ๋ ์๋ ๊ฐ์ฒด๋ฅผ ๋๊ฐ์ด ์กฐํํ๊ฒ๋๋ค
CASE 1 )
[์ฟ ํฐ ์๋ฐ๊ธฐ] ๋จผ์ ์ํ
update ~
set participate = 'N', win = 'N'
where phone is null
[์ฟ ํฐ ๋ฐ๊ธฐ] ๋จผ์ ์ํ
update ~
set participate = 'Y', win = 'Y', phone = '010-0000-0000'
where phone is null
participate์ win์ select ์ ๊ฐ์ ธ์๋ ๊ฐ์ผ๋ก ๋๊ฐ์ด ๋ฎ์ด์ฃผ์ด์ ๋น์ฒจ ์ด๋ ฅ์ด ๋จ๋๋ก ํ๋ค.
CASE 2 )
[์ฟ ํฐ ๋ฐ๊ธฐ] ๋จผ์ ์ํ
update ~
set participate = 'Y', win = 'Y', phone = '010-0000-0000'
where phone is null
[์ฟ ํฐ ์๋ฐ๊ธฐ] ๋์ค ์ํ
update ~
set participate = 'N', win = 'N'
where phone is null
phone is null ์ด ์๋๋ ํด๋น update๋ฌธ์ ์์ ๋ฌด์๋จ!!
Transactional Propagation ์ ํ
update๋ฌธ์ด ๋๊ฐ๋ ๋ค๋ฅธ๋ก์ง์์ ์๋ฌ๊ฐ ๋ฐ์ํด์ ๋กค๋ฐฑ๋๋ฉด ์๋๋๊น..
rollbackFor์ ์ฐ๊ธฐ์ ์ข.. ๋ถ๋ด๋์ด์ propgation์ ์ค์ ํด์ฃผ์๋ค
@Transactional(propagation = Propagation.REQUIRES_NEW)
public Response SendCoupone(~~){
//์ฐธ์ฌ์ ๋ณด ์ ์ฅ
saveParticipate();
//๋น์ฒจ์ ๋ณด ์ ์ฅ
saveWinner();
//์ฟ ํฐ ๋ฐ์ก
sendCoupon();
return response;
}
ํด๋น ์ค์ ์ ํด์ฃผ๋ฉด ๋งค๋ฒ ์๋ก์ด ํธ๋์ญ์ ์ ์์ํ๋ค.
์ฐธ์ฌ์ ๋ณด ์ ์ฅ ๋ฐ๋ก, ๋น์ฒจ์ ๋ณด ์ ์ฅ ๋ฐ๋ก, ์ฟ ํฐ๋ฐ์ก ๋ฐ๋ก๋ฐ๋ก ๊ฐ๊ฐ์ ํฌํ๋ฉฐ ์ปค๋ฐ๋๋ค
์์ ๋งํ [์ฟ ํฐ๋ฐ๊ธฐ], [์ฟ ํฐ์๋ฐ๊ธฐ]๊ฐ ๋์์ ๋ค์ด์ค๋ ๋น๋์๊ฐ ์๊ฐ๋ณด๋ค ์ข ์์ด์
๊ณ์ ์ ์๋ฌ๊ฐ ๋ฐ์๋๋ ์ํฉ์ด์๋ค (์ฐจ๋ผ๋ฆฌ ์ฃฝ์ฌ...)
์ผ๋จ์ update๋ฌธ๊ณผ propagation 2๊ฐ์ง ์ค์ ํ๋ ๊ฒ์ผ๋ก
๋กค๋ฐฑ๋์ด์ ๋ ์๊ฐ๋ ๋ฐ์ดํฐ๋ ์ก์๋๊ณ , ์๋ฌ ๋ฐ์ํ๋ ๋น๋์๋ ์์ฒญ ๋ฎ์ถ์๋ค!
๋ด ๋ฐฉ๋ฒ์ด ์ ๋ต์ ์๋์ง๋ง ์ด๋ ๊ฒ ํด๊ฒฐํ๋ค๋ ๊ธฐ๋ก์ฉ ํ๊ธฐ~~~ ๋!
++ ๋๊ธ ์ถ๊ฐ
์ข์ ์๊ฒฌ์ ๋จ๊ฒจ์ฃผ์ ์ ๋์ค์ ๋ค์ ์ดํด๋ณด๋ คํ๋ค!