JPA ๊ฐ์ฒด์ ์ํ / @Transactional
1. JPA ๊ฐ์ฒด์ ์ํ
1) Transient
๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ , ๊ฐ์ ์ฃผ์ด๋ JPA๋ hibernate๊ฐ ๊ทธ ๊ฐ์ฒด์ ๊ดํด ์๋ฌด๊ฒ๋ ๋ชจ๋ฅด๋ ์ํ. ์ฆ, ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋งคํ๋ ๊ฒ์ด ์๋ฌด๊ฒ๋ ์๋ค.
2) Persistent
์ ์ฅ์ ํ๊ณ ๋์, JPA๊ฐ ์๋ ์ํ(๊ด๋ฆฌํ๋ ์ํ)๊ฐ ๋๋ค. ๊ทธ๋ฌ๋ .save()๋ฅผ ํ๋ค๊ณ ํด์, ์ด ์๊ฐ ๋ฐ๋ก DB์ ์ด ๊ฐ์ฒด์ ๋ํ ๋ฐ์ดํฐ๊ฐ ๋ค์ด๊ฐ๋ ๊ฒ์ ์๋๋ค. JPA๊ฐ persistent ์ํ๋ก ๊ด๋ฆฌํ๊ณ ์๋ค๊ฐ, ํ์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ค.(1์ฐจ ์บ์, Dirty Checking(๋ณ๊ฒฝ์ฌํญ ๊ฐ์ง), Write Behind(์ต๋ํ ๋ฆ๊ฒ, ํ์ํ ์์ ์ DB์ ์ ์ฉ) ๋ฑ์ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค)
3) Detached
JPA๊ฐ ๋์ด์ ๊ด๋ฆฌํ์ง ์๋ ์ํ. JPA๊ฐ ์ ๊ณตํด์ฃผ๋ ๊ธฐ๋ฅ๋ค์ ์ฌ์ฉํ๊ณ ์ถ๋ค๋ฉด, ๋ค์ persistent ์ํ๋ก ๋์๊ฐ์ผํ๋ค.
4) Removed
JPA๊ฐ ๊ด๋ฆฌํ๋ ์ํ์ด๊ธด ํ์ง๋ง, ์ค์ commit์ด ์ผ์ด๋ ๋, ์ญ์ ๊ฐ ์ผ์ด๋๋ค.
2. @Transactional
ํ ํฐ๊ฐ์ด DB ์ ์ ์ฅ๋์ง ์์์ ํ์ธํด๋ณด๋, ๊ณ์ ์ ์ฅ ํ, ์ด๋ฉ์ผ ํ ํฐ์ ์์ฑ.
Detached ์ํ์ ๊ฐ์ฒด์๋ ๊ฒ์ด๋ค.
[AS-IS]
private Account saveNewAccount(@Valid SignUpForm signUpForm) {
Account account = Account.builder()
....
.build();
return accountRepository.save(account);
}
public void processNewAccount(SignUpForm signUpForm) {
Account newAccount = saveNewAccount(signUpForm);
newAccount.generateEmailToken();
sendSignupConfirmEmail(newAccount);
}
accountRepository.save(account) ๋ฉ์๋ ์์์๋ transaction ์ฒ๋ฆฌ๊ฐ ๋๋ค. ์ด์ ํด๋นํ๋ Entity๊ฐ JPA life cycle ์ค Persistent ์ํ๋ค.
๊ทธ๋ฆฌ๊ณ ์ด๋ฉ์ผ ์ธ์ฆ์ ์ํด ์ ์ธ๋ newAccount ๊ฐ์ฒด์ ๊ฒฝ์ฐ, Detached ์ํ์ด๋ค. ์ด๋ฏธ transcation ๋ฒ์ ๋ฐ์ด๊ธฐ ๋๋ฌธ์ Entity๋ฅผ ์์ ํ๋ค๊ณ ํด์ ๋ณ๊ฒฝ์ฌํญ์ด ์ ์ฅ๋์ง ์๋๋ค.
[TO-BE]
private Account saveNewAccount(@Valid SignUpForm signUpForm) {
Account account = Account.builder()
....
.build();
return accountRepository.save(account);
}
@Transactional
public void processNewAccount(SignUpForm signUpForm) {
Account newAccount = saveNewAccount(signUpForm);
newAccount.generateEmailToken();
sendSignupConfirmEmail(newAccount);
}
์ด ๋ @Transactional ๋ฅผ ์ฌ์ฉํ์ฌ processNewAccount์ ๊ฐ์ฒด๋ transaction ๋ฒ์๋ด์ ๋ค๋๋ก ํ๋ค. ๊ทธ๋ผ Detached ์ํ๊ฐ ์๋ Persistent ์ํ๊ฐ ์ ์ง๊ฐ ๋๋ค. Persisent ๊ฐ์ฒด์ ๊ฒฝ์ฐ, transaction์ด ์ข ๋ฃ๋ ๋ DB์ sync ๋๋ค. ๋ฐ๋ผ์, ์์ฑ๋ ํ ํฐ ๊ฐ๋ ์ ์ฅ๋๋ค.
*์ฐธ๊ณ ์๋ฃ
๋ฐฑ๊ธฐ์ ์ธํ๋ฐ ๊ฐ์