[Spring] Transaction(ํธ๋์ญ์ )
๐น Transaction์ด๋ ?
[ Transaction ํ์ ๋ฐฐ๊ฒฝ ]
๋ณต์กํ ํ๋ก๊ทธ๋จ์ ๊ฐ๋ฐํ๋ค ๋ณด๋ฉด ์ฟผ๋ฆฌ ํ ์ค๋ก ํด๊ฒฐํ ์ ์๋ ๋ก์ง์ ์ฒ๋ฆฌํด์ผ ํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง๋ค.
์ฌ๋ฌ ๊ฐ์ ์ฟผ๋ฆฌ๊ฐ ์ฒ๋ฆฌ๋๋ ์ํฉ์์ ๋ฌธ์ ๊ฐ ์๊ฒจ๋ฒ๋ฆฐ๋ค๋ฉด ์์คํ ์ ํฐ ๊ฒฐํจ์ ๋จ๊ธฐ๊ฒ ๋๋ค.
์๋ฅผ ๋ค์ด, ์ผํ๋ชฐ ์๋น์ค๋ฅผ ๊ตฌํํ ๋, ์๋์ ๊ฐ์ ๋ก์ง์ ํ ์ค๋ก ์ฒ๋ฆฌํ๋ ๊ฒ์ด ๋ถ๊ฐ๋ฅํ๋ค.
๋จผ์ ์ผํ๋ชฐ์์ ์ํ์ ๊ตฌ๋งคํ ๋, ํ์์ ์์ฌ ๊ธ์ก์ด ์ถฉ๋ถํ์ง ํ์ธํ๊ณ ์์ฌ ๊ธ์ก์ด ์ํ ๊ฐ๊ฒฉ๋ณด๋ค ๋์ ๋ ๊ตฌ๋งค ๋ก์ง์ผ๋ก ๋์ด๊ฐ์ผ ํ๋ค. ๊ทธ๋ฆฌ๊ณ ์ํ์ ์ฌ๊ณ ๊ฐ ์๋์ง ํ์ธ ํ์ ํ์์ ์์ฌ ๊ธ์ก์์ ์ํ ๊ธ์ก๋งํผ ๊ฐ์์ํค๊ณ ๋ก์ง์ ์ข ๋ฃํด์ผ ํ๋ค.
๊ทธ๋ฐ๋ฐ ์ ํ ์ํ ๊ตฌ๋งค ๋จ๊ณ์์ Exception()์ด ๋ฐ์ํ์ฌ ์ํ์ด ์์์๋ ๋ถ๊ตฌํ๊ณ ์ํ์ด ์๋ค๊ณ ํ๋จํ๊ฑฐ๋,
์์ฌ ๊ธ์ก์ด ๊ฐ์ํ๋ ์ฐฐ๋์ ์๋ฒ์ ์ ์์ด ๋๊ฐ ์ํ์ ๊ตฌ๋งคํ๋๋ฐ๋ ํ์์ ์์ฌ ๊ธ์ก์ด ๊ฐ์ํ์ง ์์ ์ ์๋ค.
์ด๋ฌํ ์ํฉ์ ์์ฒญ๋ ๋น์ฉ ์์ค์ ์ ๋ฐํ๋๋ฐ, ์ด๋ฌํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด Transaction ๊ธฐ์ ์ด ํ์ํ๊ฒ ๋์๋ค.
[ Transaction ๊ธฐ๋ณธ ๋ฐฉ๋ฒ ]
Transaction์ 2๊ฐ ์ด์์ ์ฟผ๋ฆฌ๋ฅผ ํ๋์ ์ปค๋ฅ์ (Connection)์ผ๋ก ๋ฌถ์ด DB์ ์ ์กํ๊ณ , ์ด ๊ณผ์ ์์ ์๋ฌ๊ฐ ๋ฐ์ํ ๊ฒฝ์ฐ ์๋์ผ๋ก ๋ชจ๋ ๊ณผ์ ์ ์๋๋๋ก ๋๋๋ ค ๋๋๋ค. ์ด๋ฌํ ๊ณผ์ ์ ๊ตฌํํ๊ธฐ ์ํด Transaction์ ํ๋ ์ด์์ ์ฟผ๋ฆฌ๋ฅผ ์ฒ๋ฆฌํ ๋ ๋์ผํ ์ปค๋ฅ์ (Connection) ๊ฐ์ฒด๋ฅผ ๊ณต์ ํ๋๋ก ํ๋ค.
๐น Spring์์ Transaction ์ฌ์ฉ๋ฐฉ๋ฒ
[ Spring์์ Transaction ]
Spring์ ์ฝ๋ ๊ธฐ๋ฐ์ ํธ๋์ญ์ (Programmatic Transaction) ์ฒ๋ฆฌ๋ฟ ์๋๋ผ ์ ์ธ์ ํธ๋์ญ์ (Declarative Transaction)์ ์ง์ํ๊ณ ์๋ค. Spring์์ ์ ๊ณตํ๋ ํธ๋์ญ์ ํ ํ๋ฆฟ ํด๋์ค๋ฅผ ์ด์ฉํ๊ฑฐ๋ ์ค์ ํ์ผ, ์ด๋ ธํ ์ด์ ์ ์ด์ฉํด ํธ๋์ญ์ ์ ๋ฒ์ ๋ฐ ๊ท์น์ ์ ์ํ ์ ์๋ค.
Spring์์๋ ์ฃผ๋ก ์ ์ธ์ ํธ๋์ญ์ ์ ์ด์ฉํ๋๋ฐ, <tx:advice> ํ๊ทธ ๋๋ @Transactional ์ด๋ ธํ ์ด์ ์ ์ฌ์ฉํ ์ ์๋ค.
์ด๋ ์ฟผ๋ฆฌ๋ฌธ์ ์ฒ๋ฆฌํ๋ ๊ณผ์ ์์ ์๋ฌ๊ฐ ๋ฌ์ ๊ฒฝ์ฐ ์๋์ผ๋ก Rollback ์ฒ๋ฆฌ๋ฅผ ํด์ค๋ค.
[ @Transactional ]
์ผ๋ฐ์ ์ผ๋ก Spring์์๋ Service Layer์์ @Transactional์ ์ถ๊ฐํ์ฌ ํธ๋์ญ์ ์ฒ๋ฆฌ๋ฅผ ํ๋ค.
package com.spring.store.service;
import com.spring.store.dto.StoreDTO;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
public interface StoreService {
List<StoreDTO> selectStoreInfoList(StoreDTO storeDTO);
StoreDTO selectStoreInfo(StoreDTO storeDTO);
int insertStoreInfo(StoreDTO storeDTO);
int updateStoreInfo(StoreDTO storeDTO);
int deleteStoreInfo(StoreDTO storeDTO);
}
package com.spring.store.service.impl;
import com.spring.store.dto.StoreDTO;
import com.spring.store.service.StoreService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
public class StoreServiceImpl implements StoreService {
@Override
public List<StoreDTO> selectStoreInfoList(StoreDTO storeDTO) {
return null; // ๋ฐ์ดํฐ ์กฐํ ๋ก์ง ๊ตฌํ
}
@Override
public StoreDTO selectStoreInfo(StoreDTO storeDTO) {
return null; // ๋ฐ์ดํฐ ์กฐํ ๋ก์ง ๊ตฌํ
}
@Transactional
@Override
public int insertStoreInfo(StoreDTO storeDTO) {
return 0; // ๋ฐ์ดํฐ ์ฝ์
๋ก์ง ๊ตฌํ
}
@Transactional
@Override
public int updateStoreInfo(StoreDTO storeDTO) {
return 0; // ๋ฐ์ดํฐ ์์ ๋ก์ง ๊ตฌํ
}
@Transactional
@Override
public int deleteStoreInfo(StoreDTO storeDTO) {
return 0; // ๋ฐ์ดํฐ ์ญ์ ๋ก์ง ๊ตฌํ
}
}
์ ์์ ์์๋ ๋ฐ์ดํฐ ์กฐํ๋ง ์ํํ๋ select ๋ฉ์๋์๋ @Transactional๋ฅผ ์ ์ฉํ์ง ์์๊ณ ,
๋ฐ์ดํฐ๋ฅผ ๋ณ๊ฒฝํ๋ insert, update, delete ๋ฉ์๋์๋ง @Transactional์ ์ ์ฉํ์ฌ ํธ๋์ญ์ ์ ์ค์ ํ๋ค.
์กฐํ ๋ฉ์๋๋ ํธ๋์ญ์ ์ด ํ์์ ์ด์ง ์์ง๋ง, ์ฝ๊ธฐ ์ ์ฉ ํธ๋์ญ์ (@Transactional(readOnly = true))์ ์ ์ฉํ๋ฉด ์ฑ๋ฅ ์ต์ ํ๊ฐ ๊ฐ๋ฅํ๋ค.
๋ฐ๋ฉด, insert, update, delete ๊ฐ์ ๋ฐ์ดํฐ ๋ณ๊ฒฝ์ด ๋ฐ์ํ๋ ๋ฉ์๋์๋ ํธ๋์ญ์ ์ ์ ์ฉํ๋ฉด ์์ธ ๋ฐ์ ์ ์๋์ผ๋ก ๋กค๋ฐฑ(rollback) ๋๋๋ก ์ค์ ํ ์ ์๋ค.
๋ํ, @Transactional์ ์ธํฐํ์ด์ค๊ฐ ์๋ ๊ตฌํ ํด๋์ค์ ์ ์ฉํ๋ ๊ฒ์ด ์ผ๋ฐ์ ์ด๋ค.
์ด๋ Spring์ AOP ๊ธฐ๋ฐ ํธ๋์ญ์ ๊ด๋ฆฌ ๋ฐฉ์ ๋๋ฌธ์ด๋ฉฐ, ์ธํฐํ์ด์ค์ ์ ์ฉํ ๊ฒฝ์ฐ ํธ๋์ญ์ ์ด ์ ์์ ์ผ๋ก ์๋ํ์ง ์์ ์ ์๋ค.