6. AOP
AOP
AOP๋ IoC/DI, ์๋น์ค ์ถ์ํ์ ํจ๊ป Spring 3๋ ๊ธฐ๋ฐ ๊ธฐ์ ์ด๋ค ๊ด์ ์งํฅ ํ๋ก๊ทธ๋๋ฐ... ํธ๋์ญ์ ์์ ์์ ํธ๋์ญ์ ์ฝ๋์ ๋น์ฆ๋์ค ์ฝ๋์ ๋ถ๋ฆฌ -> ์ฌ๊ธฐ์์ ํธ๋์ญ์ ์ฝ๋ ๊ฐ์ ๊ฒฝ์ฐ๋ ๋์ผํ๊ฒ ์ฌ์ฉ๋ ์ ์๋ค. ๋ถ๋ฆฌ๋ฅผ ํ์ฌ ๋ฐ๋ก ์์ฑํ๋ฉด์ ์ ์ ํ ํธ๋์ญ์ ์ ๋ํ ์ฒ๋ฆฌ!
์ฌ๊ธฐ์์ ๋ฑ์ฅํ๋ ๊ฐ๋ ์ด AOP
@Autowired์ ๋ฌธ์ ์
type ๊ธฐ๋ฐ์ผ๋ก ๋น์ ์ฐพ์
-> ์์ํ์ Autowired์ผ ๊ฒฝ์ฐ ํ์ํ์ ์ด 2๊ฐ์ด์์ด๋ฉด ์๋ฌ ๋ฐ์.. (์ ๋งคํ๋ค๊ณ ์๋ ค์ค)
๊ณ ๋ฆฝ๋ ๋จ์ ํ
์คํธ
ํ
์คํธ์ ๊ฐ์ฅ ์ข์ ๋จ์๋ ๊ฐ๋ฅํ ๊ฐ์ฅ ์๊ฒ ์ชผ๊ฐ์ ํ
์คํธ
ํ ์คํธ ์คํจ์ ์์ธ ๋ถ์์ด ๋น ๋ฆ
ํ
์คํธ ๋์์ ์์กด๋์
A๋ฅผ ํ ์คํธํ๊ณ ์ถ์๋ฐ A์ ๊ด๊ณ๋ฅผ ๊ฐ๋ B,C,D ํด๋์ค๊ฐ ์กด์ฌํ๋ ๊ฒฝ์ฐ ๊ทธ๋ฆฌ๊ณ B,C,D๋ ๋ ๊ฐ๊ฐ ์์กด๊ด๊ณ๋ฅผ ๊ฐ๋ ๋ค๋ฅธ ํด๋์ค๋ ์กด์ฌ ํ ๊ฒ์ด๋ค. ์ฆ ์ฌ๋ฌ๊ณณ์ ์ํฅ์ ๋ฐ๊ฑฐ๋ ๋ฏธ์น๊ณ ์๋์ .. ์ด๋ด ๊ฒฝ์ฐ ํ ์คํธ๋ A๋ฅผ ํ๊ณ ์ถ์๋๋ฐ.. ๋ค๋ฅธ๊ฒ ๋ ์ ๊ฒฝ์ฐ์ด๊ฒ ๋๋ฒ๋ฆฌ๋ ํ์์ด ๋์ค๋ ๊ฒ์ด๋ค.
ํ
์คํธ ๋์ ์ค๋ธ์ ํธ ๊ณ ๋ฆฝ
๊ทธ๋์ ํ
์คํธ์ ๋์์ด ํ๊ฒฝ, ์ธ๋ถ์๋ฒ, ๋ค๋ฅธํด๋์ค์ ์ฝ๋์ ์ข
์๋๊ณ ์ํฅ์ ๋ฐ์ง ์๋๋ก ๊ณ ๋ฆฝ์์ผ์ผํ๋ค.
-> ๋ชฉ์ค๋ธ์ ํธ ์์ฑ์ ํ์ฌ ์ ์ ํ ๊ตฌํ -> ๊ตฌํ์ ์ฌ์ฉ์ํ๋ ๋ฉ์๋๋
๋จํ
, ํตํ
๋จํ
์ ๊ฒฝ์ฐ๋ฅผ ํญ์ ๋จผ์ ์๊ฐ, ์ธ๋ถ ๋ฆฌ์์ค๋ฅผ ์ฌ์ฉํด์ผํ๋ ๊ฒฝ์ฐ ํตํ
, ๋จํ
์ ์ด๋ ค์ (ex DAO)๋ ์กด์ฌ.
์คํ๋ง ํ
์คํธ ์ปจํ
์คํธ ํ๋ ์์ํฌ
-> ํตํฉํ
์คํธ
Mockito ํ๋ ์์ํฌ
๋ชฉ์ ๊ธฐ๋ฐ์ด ๋๋ ๊ฐ๋
์ด ํ๋ก์์ ์คํ
๊ฐ์ ๋๋
๋ชฉ์ค๋ธ์ ํธ
๋ฅผ ์ผ์ผ์ด ์์ฑํ๋ ๊ฒ์ ๋์ ํด์ฃผ๋ ํ๋ ์์ํฌ, ์ฆ ๊ธฐ์กด์ฒ๋ผ ์์ฑํ ํ์๊ฐ ์์!! ๊ฐ์ ๋ฐํจ!!!
Java ํด๋์ค ์ํฌํธ
๋ผ์ด๋ธ๋ฌ๋ฆฌ maven ์ถ๊ฐ
๋ค์ด๋ด๋ฏน ํ๋ก์์ ํฉํ ๋ฆฌ๋น
๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ mock, when, thenReturn, verify, times, any ๋ฉ์๋
๋ฐ์ฝ๋ ์ดํฐ ๋ฐ์ฝ๋ ์ดํฐ ํจํด.. ๋ํจ์์ ๋ฐฐ์ ๋ ๋ด์ฉ ์์ฝ.. ๋์ ์ผ๋ก ๊ธฐ๋ฅ์ ์ถ๊ฐํ ์ ์๊ฒ ๊ตฌํ๋ ํจํด
ํ๋ก์ ํ๋ก์, ๋๋ฆฌ์ธ ์ญํ, ์ ๊ทผ์ ์ด, ์คํ ๊ณผ ๋ชฉ์ ๊ธฐ๋ฐ์ด๋๋ ๊ฐ๋ RMI ๋ฑ ์๊ฒฉ ํ๋ก์ ํ๊ฒ ์ธํฐํ์ด์ค์ ์์, ์ค์ ํ์ํ ๊ฒฝ์ฐ ์ค์ object๋ฅผ ํธ์ถ
๋ฆฌํ๋ ์ ํด๋์ค์ ๋ํ ์ ๋ณด๋ฅผ ์ป๊ฑฐ๋, ์ธ์คํด์ค ์์ฑ ๋ฑ ๋์ ์ผ๋ก ๊ตฌํํ ์ ์์
X.class ๋ x.getClass()
๋ฅผ ํ์ฉํ์ฌClass ํด๋์ค
๋ฅผ ํตํด ์ ๋ณด๋ฅผ ์ป์ ์ ์์๋ค์ด๋๋ฏน proxy ํด๋์ค
```java
// Hello ์ธํฐํ์ด์ค public interface Hello { String sayHello(String name);
String sayHi(String name);
String sayThankYou(String name); }
// ํ๊ฒ ์ค๋ธ์ ํธ public class HelloTarget implements Hello { @Override public String sayHello(String name) { return "Hello " + name; }
@Override public String sayHi(String name) { return "Hi " + name; }
@Override public String sayThankYou(String name) { return "Thank You " + name; } }
// ๋ค์ด๋๋ฏน Proxy์์ ์ฌ์ฉํ ๋ถ๊ฐ๊ธฐ๋ฅ : InvocationHandler๋ฅผ ๊ผญ ๊ตฌํํด์ผํจ public class UppercaseHandler implements InvocationHandler { Hello target; // ํ๊ฒ ์ธํฐํ์ด์ค
public UppercaseHandler(Hello target) { this.target = target; }
@Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String ret = (String) method.invoke(target, args); return ret.toUpperCase(); } }
๋ค์ด๋๋ฏน Proxy์ ๋จ์ ์... ํ๊น ์ค๋ธ์ ํธ๊ฐ ๋์ด๋๋ฉด ๊ทธ๋งํผ Proxy๋ฅผ ๋ง๋ค์ด์ค์ผํ๋... ์ํฉ์ด ๋ฐ์... -> ๊ทธ๋ ๊ฒ๋๋ค๋ณด๋ฉด ์ค์ ๋ถ๋ถ๋ ์ค๋ณต... -> ํด๊ฒฐ์ฑ ์ ? ํฉํ ๋ฆฌ๋น -> ํฉํ ๋ฆฌ๋น -> ์คํ๋งํฉํ ๋ฆฌ๋น
์คํ๋ง์ ํ๋ก์ ํฉํ ๋ฆฌ ๋น
ํ๋ก์ ์ค๋ธ์ ํธ๋ฅผ ์์ฑํด์ฃผ๋ ๊ธฐ์
์ ์ถ์ํํ ํฉํ ๋ฆฌ ๋น
ProxyFactoryBean
์์ํ๊ฒ Proxy ์์ฑ๋ง ๋ด๋น. ๊ธฐ์กด์ ํธ๋์ญ์ ๋ถ๊ฐ๊ธฐ๋ฅ์ด ๋ค์ด๊ฐ ๋ง๋ TxProxyFactoryBeanํ๊ณ ๋ ๊ธฐ๋ฅ๋ง ๋ค๋ฆ
์ฆ ์์ Proxy ์์ฑ๋ง ๋ด๋น / ๋ถ๊ฐ๊ธฐ๋ฅ์ ๋ฐ๋ก ์ ์ํ์ฌ ์ฌ์ฉ
๊ธฐ๋ฅ๊ณผ ์ญํ์ ๋ถ๋ฆฌ.... ๋ฏธ์น๋ฏํ ์ค๊ณ.. ๊ฐํ
org.aopalliance.intercept.MethodInterceptor extends Advice
๋ถ๊ฐ๊ธฐ๋ฅ์
MethodInterceptor ์ธํฐํ์ด์ค ๊ตฌํ
์ ํตํด ๋ง๋ฌInvocationHandler ์ธํฐํ์ด์ค์ ๋ค๋ฅด๋ค -> ์ด๋ ์์ invoke ๋ฉ์๋์์๋ ํ๊น์ค๋ธ์ ํธ์ ์ ๋ณด๋ฅผ ์ ๊ณตํ์ง ์์
MethodInterceptor์ invoke ๋ฉ์๋ -> ProxyFactoryBean์ผ๋ก ๋ถํฐ ํ๊น์ค๋ธ์ ํธ๋ฅผ ์ ๊ณต ๋ฐ์. ๋ฐ๋ผ์ ํ๊น์ค๋ธ์ ํธ์ ๊ตฌ์ ๋ฐ์ง ์๊ณ ๋ ๋ฆญ์ ์ผ๋ก ๊ตฌํ ๊ฐ๋ฅ
๊ทธ๋์ ์ฌ๋ฌ ํ๋ก์์ ํจ๊ป ์ฌ์ฉ, ์ฑ๊ธํค ๋น ๋ฑ๋ก ๊ฐ๋ฅ
invoke ๋ฉ์๋์ ๊ฒฝ์ฐ ->
methodInvocation.proceed()
๋ Method์ ๋ฌ๋ฆฌํ๊น ์ ๋ณด๋ฅผ ํจ๊ผ ์ ๋ฌํ๋ค
Advice ์ธํฐํ์ด์ค๋ฅผ ์์
ํ๋ ์ธํฐํ์ด์ค
์ด๋๋ฐ์ด์ค ! (ํ๊น์ค๋ธ์ ํธ๊ฐ ํ์์๋ ์์ํ ๋ถ๊ฐ๊ธฐ๋ฅ
)
์์ํ ๋ถ๊ฐ๊ธฐ๋ฅ
)MethodInvocation ๊ฐ์ ๊ฒฝ์ฐ ํ๊น์ค๋ธ์ ํธ์ ํจ๊ป ์ ๋ฌํ์ฌ ์คํํ๊ฒ ๋๋ฉฐ, ๋ถ๊ฐ๊ธฐ๋ฅ ๊ตฌํ์๋ง ์ง์คํ ์ ์๋๋ก ํจ ๊ธฐ ๊ตฌํํ๋ InvocationHandler์์ ์ฐจ์ด์ ์ด๋ค.
MethodInvocation์ ์ผ์ข ์ ์ฝ๋ฐฑ ์ค๋ธ์ ํธ, procced ๋ฉ์๋ ->
ํ๊น์ค๋ธ์ ํธ์ ๋ฉ์๋๋ฅผ ๋ด๋ถ์ ์ผ๋ก ์คํ
ProxyFactoryBean.addAdvice() -> ์ฌ๋ฌ ๊ฐ์ MethodInvocation์ ์ถ๊ฐํ ์ ์๋ค๋ ์ฅ์
-> ์ฆ, ProxyFactoryBran์ ์ฌ๋ฌ ๊ฐ์ง ๋ถ๊ฐ๊ธฐ๋ฅ์ ๋ฃ์ ์ ์์์ ์๋ฏธ
ํ๊น์ ๋ถ๊ฐ๊ธฐ๋ฅ์ ์ ์ฉํ๋ ๊ฒ์
์คํ๋ง์์๋ ์ด๋๋ฐ์ด์ค
๋ผ๊ณ ํ๋ค์์ํ ๊ธฐ๋ฅ์ ๋ด์ ์ค๋ธ์ ํธ๋ผ ํ ์ ์์
ํฌ์ธํธ ์ปท ! ๋ถ๊ฐ๊ธฐ๋ฅ ์ ์ฉ๋์์ ๋ฉ์๋ ์ ์
๋ฉ์๋ ์ ์ ์๊ณ ๋ฆฌ์ฆ ProxyFactoryBean -> Advice(๋ถ๊ฐ๊ธฐ๋ฅ) + PointCut(๋์๋ฉ์๋) ๊ด๋ฆฌ ๋ฐ ์ ์ฉ
NameMatchMethodPointcut (์คํ๋ง ์ ๊ณต)
์ด๋๋ฐ์ด์ = advice + pointcut
DefaultPointcutAdvisor (์คํ๋ง ์ ๊ณต)
์ด๋๋ฐ์ด์ค ๋ฐ๋ก, ํฌ์ธํธ์ปท ๋ฐ๋ก ๋ฑ๋ก์ ์ํ๋ ์ด์ ๋ ์ด๋ค ์ด๋๋ฐ์ด์ค์ ์ด๋ค ํฌ์ธํธ์ปท์ด ์ ์ฉ๋ ์ง ์ ๋งคํด์ง๊ธฐ ๋๋ฌธ์ด๋ค.
๋ฐ๋ผ์ ์ด๋๋ฐ์ด์ ๋ก ๋ฑ๋ก์ ํด์ผํ๋ค.
xml ์ค์
interceptorNames ์์ฑ -> ์ด๋๋ฐ์ด์ค์ ์ด๋๋ฐ์ด์ ๋ฅผ ํผํฉ
ํด์ ์ค์ ๊ฐ๋ฅํ๋ค
์คํ๋ง AOP
ํฌ๋ช ์ฑ : ๋ถ๋ฆฌ๋ฅผ ํตํด ํฌ๋ช ํ ๋ถ๊ฐ๊ธฐ๋ฅ ํํ๋ก ์ ๊ณต ๋์ด์ผํจ. ํฌ๋ช ํ๋ค๋ ๊ฒ์ ๋ง์น ํฌ๋ช ํ ์ ๋ฆฌ๋ฅผ ์ฌ์ด์ ๋๊ฒ ๊ฐ๋ค๋ ๊ฒ. OCP๊ฐ๋ ์ด๋ผ๊ณ ๋ณผ ์ ๋ ์๋ค. ์ถ๊ฐ, ์ ๊ฑฐ ๋ฐ ํ์ฅ์๋ ํญ์ ์ด๋ ค ์์ด์ผ ํ๋ค๋ ๊ฒ. DI์ ๋ฉ์ง ์์ฉ๋ฐฉ์
๋นํ์ฒ๋ฆฌ๊ธฐ
๋ง ๊ทธ๋๋ก ์คํ๋ง Bean ์์ฑ ํ ํ๊ฐ๊ณต์ ํ ์ ์๋ ๋ผ์ดํ ์ฌ์ดํด.
BeanPostProcessor ์ธํฐํ์ด์ค
ํฌ์ธํธ์ปท์ 2๊ฐ์ง ๊ธฐ๋ฅ
๋ฉ์๋ ์ ์ -> MethodMatcher
์ค๋ธ์ ํธ ์ ํ -> ClassFilter
DefaultAdvisorAutoProxyCreator
ํ๋ก์ ์ ์ฉ ๋์์ด๋ฉด, ํ๋ก์ ์ค๋ธ์ ํธ๋ฅผ ์์ฑ -> ํ๊ฒ์ค๋ธ์ ํธ์ ์ฐ๊ฒฐ -> ํ๋ก์๋ฅผ ํตํด์๋ง ์ ๊ทผ ๊ฐ๋ฅ ์๋ํ๋ก์ ์์ฑ์ ๋น ํ์ฒ๋ฆฌ๊ธฐ
ํฌ์ธํธ์ปท ํํ์์ ์ด์ฉํ ํฌ์ธํธ์ปท
AspectJExpressionPointcut ํด๋์ค ์ฌ์ฉ
AspectJ๋ผ๋ ์ธ๋ถ ํ๋ ์์ํฌ๋ฅผ ํ์ฅํ์ฌ ์คํ๋ง์์ ์ฌ ๊ฐ๊ณต์ฒ๋ฆฌ
AspectJ์ execution ์ง์์๋ฅผ ํตํด ์ค์
execution([์ ๊ทผ์ ํ์ ํจํด] ํ์ ํจํด [ํ์ ํจํด.] ์ด๋ฆํจํด (ํ์ ํจํด|"..", ...))([throws ์์ธํจํด])
์์ผ๋์นด๋ : ๊ทธ์ธ -
*
, ํ๋ผํฐ๋จธ -..
๋ชจ๋ ํจํค์ง, ํด๋์ค, ๋ฉ์๋์ด๋ฆ, ์์ธ์ด๋ฆ, ๋ฆฌํดํ์ ์ ์์ผ๋์นด๋ ์ ์ฉ๊ฐ๋ฅ
ํด๋์ค :
..
-> ์๋ธํจํค์ง / com..Target.* -> com์ผ๋ก ์์ํ๋ ํจํค์ง์์ Targetํด๋์ค์ ๋ชจ๋ ๋ฉ์๋ํ์ :
๋ฆฌํดํ์ , ๋ฉ์๋, ํ๋ผ๋ฏธํฐ
/ ๋๋จธ์ง ์๋ต๊ฐ๋ฅํฌ์ธํธ์ปท ํ์ ์ -> ์ธํฐํ์ด์ค, ์ถ์ํด๋์ค๋ ํฌ์ธํธ์ปท ์ ์ ๊ฐ๋ฅ
AspectJExpressionPointcut ์ฌ์ฉ์ ์๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ถ๊ฐ (Maven)
Java -> setExpression์ผ๋ก execution ์ค์ -> ํฌ์ธํธ์ปท ํด๋์คํํฐ, ๋ฉ์๋๋งค์ฒ ๋น๊ต
Test
```java @Test public void pointcut() throws Exception { targetClassPointcutMatches("execution( (..))", true, true, true, true, true, true); targetClassPointcutMatches("execution( hello(..))", true, true, false, false, false, false); targetClassPointcutMatches("execution( hello())", true, false, false, false, false, false); targetClassPointcutMatches("execution( hello(String))", false, true, false, false, false, false); targetClassPointcutMatches("execution( meth(..))", false, false, false, false, true, true); targetClassPointcutMatches("execution( (int,int))", false, false, true, true, false, false); targetClassPointcutMatches("execution( ())", true, false, false, false, true, true); targetClassPointcutMatches("execution( .Target.(..))", true, true, true, true, true, false); targetClassPointcutMatches("execution( chap06_AOP.Target.(..))", true, true, true, true, true, false); targetClassPointcutMatches("execution( chap06_AOP...(..))", true, true, true, true, true, true); targetClassPointcutMatches("execution( ..Target.(..))", true, true, true, true, true, false); targetClassPointcutMatches("execution( ..Tar.(..))", true, true, true, true, true, false); targetClassPointcutMatches("execution( ..get.(..))", true, true, true, true, true, false); targetClassPointcutMatches("execution( ..B.(..))", false, false, false, false, false, true); targetClassPointcutMatches("execution( ..TargetInterface.(..))", true, true, true, true, false, false); targetClassPointcutMatches("execution( (..) throws Runtime)", false, false, false, true, false, true); targetClassPointcutMatches("execution(int (..))", false, false, true, true, false, false); targetClassPointcutMatches("execution(void (..))", true, true, false, false, true, true); }
private void targetClassPointcutMatches(String expression, boolean... expected) throws Exception{ pointcutMatches(expression, expected[0], Target.class, "hello"); pointcutMatches(expression, expected[1], Target.class, "hello", String.class); pointcutMatches(expression, expected[2], Target.class, "plus", int.class, int.class); pointcutMatches(expression, expected[3], Target.class, "minus", int.class, int.class); pointcutMatches(expression, expected[4], Target.class, "method"); pointcutMatches(expression, expected[5], Bean.class, "method");
}
private void pointcutMatches(String expression, Boolean expected, Class<?> clazz, String methodName, Class<?>... args) throws Exception { AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut(); pointcut.setExpression(expression);
}
6.6 ํธ๋์ญ์
์์ฑ
ํธ๋์ฐ์ ๋งค๋์ :
PlatformTransactionManager
ํธ๋์ญ์ ์ ์ :
DefaultTransactionDefinition
ํธ๋์ญ์
์ ์
์ต์์ ์์ ๋จ์. TransactionDefinition ์ธํฐํ์ด์ค 4๊ฐ์ง ์์ฑ ์ ์
ํธ๋์ญ์ ์ ํ ์ด๋ฏธ ์งํ ์ค์ธ ํธ๋์ญ์ ์ด ์์ ๋ or ์์ ๋ ์ด๋ป๊ฒ ๋์ํ ๊ฒ์ธ์ง ๊ฒฐ์ ํ๋ ๋ฐฉ์ Aํธ๋์ญ์ ์คํ ์ค Bํธ์ถ -> B๋ A์ ํธ๋์ญ์ ์์ ์๋ค. ์ด๋ด ๊ฒฝ์ฐ ์ทจ์๋๋ฉด ๋๋ค ๋กค๋ฐฑ B๊ฐ ๋ ๋ฆฝ์ ์ธ ํธ๋์ญ์ ์ ๊ฐ๊ณ ์๊ณ , B๋ ๋๋์ํ์์ A๊ฐ ์์ธ๋ก ์ทจ์๋๋ฉด A๋ง ๋กค๋ฐฑ
PROPAGATION_REQUIRED ์์ฑ (๊ฐ์ฅ๋ง์ด ์ฌ์ฉ) : ์์ผ๋ฉด ๊ทธ๊ฑฐ์ฐ๊ณ , ์์ผ๋ฉด ์๋ก๋ง๋ฌ -> ์ฌ์ฌ์ฉ
PROPAGATION_REQUIRED_NEW : ํญ์ ์๋ก์ด ํธ๋์ญ์ ์์ฑ
PROPAGATION_NOT_SUPPORTED : ์ ์ธํ๊ณ ์ ํ ๋ ๋ง์ด ์ฐ์
๊ฒฉ๋ฆฌ์์ค ์๋ฒ์์๋ ์ฌ๋ฌ๊ฐ์ ํธ๋์ญ์ ์ด ๋์์ ๋ฐ์ํ ์ ์๋ค. ์ด๊ฒ์ ์ ์ดํด์ค์ผํจ
ISOLATION_DEFAULT
,Datasoruce
์ ๋ํดํธ๋ฅผ ๋ฐ๋ฅด๋ ํธ์ด ์ข์ง๋ง, ๋์ ๋ฐ๋ผ์๋ ๋ ์์ ์ธ ๊ฒฉ๋ฆฌ์์ค ํ์์ ํ์๊ฐ ํธ๋์ญ์ ์ ์ํ ์ ํ์๊ฐ ์ค์ DefaultTransactionDefinition ์
๊ธฐ๋ณธ๊ฐ์ ์ ํ์๊ฐ ์์
PROPAGATION_REQUIRED or PROPAGATION_REQUIRES_NEW ์ ํจ๊ป ์ฌ์ฉํด์ผ๋ง ์๋ฏธ ์์์ฝ๊ธฐ ์ ์ฉ ๋ฐ์ดํฐ์ ์กฐ์์ ๋ง์. ์กฐํ๊ธฐ๋ฅ์ readonly ๋ก ์ค์ ํ๋ฉด ์ฑ๋ฅ์ด ํฅ์๋ ์ ์์
ํธ๋์ญ์
์ธํฐ์
ํฐ์ ํธ๋์ญ์
์์ฑ
๋ฉ์๋๋ณ๋ก ๋ค๋ฅธ ํธ๋์ญ์
์ ์ -> ์ด๋๋ฐ์ด์ค ๊ธฐ๋ฅ ํ์ฅ
TransactionInterceptor ๋ฉ์๋ ์ด๋ฆ ํจํด์ ์ด์ฉํ์ฌ ๋ค๋ฅด๊ฒ ์ง์ ํ ์ ์์ ๋ฐํ์ ์์ธ ๋ฐ์ -> ๋กค๋ฐฑ ๊ฒ์ฌ์์ธ ๋ฐ์ -> ์ปค๋ฐ 1. PlatformTransactionManager 2. Properties
TransactionAttribute ์ ์ (ํธ๋์ญ์ ์์ฑ 4๊ฐ ์ด์ฉ)
rollbackOn ๋ฉ์๋ : ์ด๋ค ์์ธ ๋ฐ์์ ๋กค๋ฐฑํ ๊ฒ์ธ๊ฐ๋ฅผ ๊ฒฐ์ .
๋ฐํ์-> ์ปค๋ฐ ๋ฑ ๋ณ๊ฒฝํ์์ ์ ์
tx๋ค์์คํ์ด์ค ์ฌ์ฉ tx์คํค๋ง ์ ์ฉ ํ๊ทธ -> ์์ ํธ๋์ญ์ ์์ฑ ๋ช ์ ์๋์์ฑ. ์คํ์จ ์ค์
ํฌ์ธํธ์ปท๊ณผ ํธ๋์ญ์
์์ฑ์ ์ ์ฉ ์ ๋ต
aop, tx ์ค์นด๋ง์ ์ ์ฉํ๊ทธ ์ฌ์ฉ, ํฌ์ธํธ์ปท์ execution ํ์ฉ
ํธ๋์ญ์ ํฌ์ธํธ์ปท ํํ์ ->
ํ์ ํจํด
or๋น์ด๋ฆ
์ด์ฉ -> execution(ํ์ ํจํด), bean(๋น์ด๋ฆ)๊ฐ๊ธ์ ํ์ ํจํด์ ์ธํฐํ์ด์คํ์ ์ฌ์ฉ ๊ถ์ฅ
๊ณตํต๋ ๋ฉ์๋ ์ด๋ฆ๊ท์น -> ์ต์ํ์ ํธ๋์ญ์ ์ด๋๋ฐ์ด์ค์ ์์ฑ ์ ์ ํ๋๋ก... ์ผ๋ฐ์ ์ธ ๊ฒฝ์ฐ๊ฐ ์๋ ๋ -> ์ด๋๋ฐ์ด์ค์ ํฌ์ธํธ์ปท ์๋กญ๊ฒ ์ถ๊ฐ
tx:advice์ aop ์ด์ฉํ ๋ฐฉ์
ํ๋ก์ ๋ฐฉ์ AOP๋ ๊ฐ์ ํ๊น์ค๋ธ์ ํธ ๋ด์ ๋ฉ์๋๋ฅผ ํธ์ถํ ๋๋ ์ ์ฉ ๋์ง ์๋๋ค...
(์ฃผ์์ฌํญ)
ex) ๊ฐ์ ํ๊น ๋ด์ ๋๋ฉ์๋์ ๋ํด delete()๊ฐ
update() ํธ์ถ
ํ๋ฉดupdate()
์ ์ ์ฉ ๋ ํธ๋์ญ์ ๊ด๋ จ advice๊ฐ ์ ์ฉ ๋์ง ์๊ณ ,delete()
์ ์ข ์๋์ด ์ ์ฉ์ด ๋๋ค. (delete๋ ํด๋ผ์ด์ธํธ์์ ํธ์ถ, ์ค์ ๋ก๋ ํธ๋์ญ์ Proxy๊ฐ ํ๊น์ ํ์ถํ ๋ ์ ์ฉ)ex) ์ ์๋ delete๊ฐ ํธ๋์ญ์ ๊ด๋ จ ์ด๋๋ฐ์ด์ค๋ก ๋ฑ๋ก๋ ์ผ์ด์ค์ง๋ง, ๋ง์ฝ์ ํธ๋์ญ์ ์ด๋๋ฐ์ด์ค๊ฐ ์๋ ํ๊น๋ฉ์๋๊ฐ
update
๋ฅผ ํธ์ถ ํ๋ค๋ฉด ์์ ํธ๋์ญ์ ์ด๋๋ฐ์ด์ค๊ฐ ์ ์ฉ์กฐ์ฐจ ์๋๋ ๊ฒฝ์ฐ๊ฐ ๋ฐ์๊ธฐ๋ณธ์ ์ธ ์ฝ๊ธฐ์ ์, REQUIRED ๊ฐ์ ์์ฑ์์๋ ๋ฌธ์ ๋์ง ์์ง๋ง, ๋ณต์กํ ํธ๋์ญ์ ์ ํ์์ฑ์ ๋ช ์ํด์ผํ ๊ฒฝ์ฐ์๋ ๊ฐ๋ณํ ์ฃผ์๊ฐ ํ์ํ๋ค!!
์ ๋ฆฌ
์คํ๋ง์ ๊ธฐ๋ณธ์ ์ผ๋ก ํ๋ก์๊ธฐ๋ฐ์ AOP๋ฅผ ์ฌ์ฉํ์ง๋ง(ํ๋ก์์ฌ์ฉ์ ๋ฌธ์ ์ ์ ์์์ ์ธ๊ธ), ํ์ํ๋ค๋ฉด AspectJ ๊ฐ์ ๋ฐ์ดํธ์ฝ๋๋ฅผ ์กฐ์ํ๋ ๋ฒ์ฉ์ ์ธ AOP๊ธฐ์ ์ ์ฌ์ฉ ํ๋ฉด๋๋ค. ๊ท์ฐฎ์ ์์ ๋ ๋ค๋ฐ๋ฅด๊ธด ํ์ง๋ง ์ด๋งํ ๊ธฐ์ ์ด ์๋ค! ๋!
ํธ๋์ญ์
์์ฑ ์ ์ฉ
๋น์ฆ๋์ค ๋ก์ง์ ๋ด๊ณ ์๋ ์๋น์ค ๊ณ์ธต ์ค๋ธ์ ํธ์ ๋ฉ์๋๊ฐ ํธ๋์ญ์
๊ฒฝ๊ณ๋ฅผ ๋ถ์ฌํ๊ธฐ
์ ๊ฐ์ฅ ์ ์ ํ ๋์
๋ถ๊ฐ๋ก์ง ๋ฐ ํธ๋์ญ์
์์ฑ์ ๋ถ๋ฆฌํ์ฌ ์ ์ฉํ๊ธฐ ์ํด์.. ์๋น์ค -> DAO
๋ก ์ ๊ทผํ๋๋ก ๊ตฌํ (์ด๋ป๊ฒ ๋ณด๋ฉด MVCํจํด?) tx์คํค๋ง์์ propagation ์์ฑ ์๋ต -> ๋ํดํธ : REQUIRED
6.7 ์ ๋
ธํ
์ด์
ํธ๋์ญ์
์์ฑ๊ณผ ํฌ์ธํธ์ปท
์ค์ ํ์ผ๋ก ์ ์ฉํ๋ ๊ฒ ๋์ ์ ํ๊ฒ์ ํธ๋์ฐ์
์ ๋ณด๋ฅผ ๊ฐ์ง ์ ๋
ธํ
์ด์
์ ์ง์ ํ ์ ์์
ํธ๋์ญ์
์ ๋
ธํ
์ด์
@Transactional
ํ๊น์
๋ฉ์๋์ ํ์
-> ๋ฉ์๋, ํด๋์ค, ์ธํฐํ์ด์ค์ ์ ์ฉ ๊ฐ๋ฅํ๊ฒ์ค๋ธ์ ํธ๋ก ์๋ ์ธ์ํจ
ํธ๋์ญ์ ์์ฑ์ ์ ์ + ํฌ์ธํธ์ปท ์๋๋ฑ๋ก
TransactionAttributeSourcePointcut
์ฌ์ฉ
ํธ๋์ญ์ ์์ฑ์ ์ด์ฉํ๋ ํฌ์ธํธ์ปท
AnnotationTransactionAttributeSource ์ฌ์ฉ -> ํฌ์ธํธ์ปท + ํธ๋์ญ์ ์์ฑ ์ง์
๋ถ๊ฐ๊ธฐ๋ฅ ์ ์ฉ ๋จ์๋ ๋ฉ์๋ -> ๋์ผํ ํธ๋์ญ์ ์์ฑ์ด ๋ํ๋ ์ ์๋ค... ->
์ง์ ๋ถํด์ง ๋จ์
๋์ฒด์ ์ฑ
์์ ๋ฌธ์ ํด๊ฒฐ -> ์คํ๋ง์์ 4๋จ๊ณ ๋์ฒด ์ ์ฑ
ํ๊น๋ฉ์๋, ํ๊นํด๋์ค, ์ ์ธ๋ฉ์๋, ์ ์ธํ์ (ํด๋์ค, ์ด๋กํ์ด์ค) ์์์ ๋ฐ๋ผ @Transactional์ด ์ ์ฉ ๋๋์ง ์ฐจ๋ก๋ก ํ์ธ -> ๊ฐ์ฅ๋จผ์ ๋ฐ๊ฒฌ๋๋ ์์ฑ์ ๋ณด๋ฅผ ์ฌ์ฉํจ
์ธํฐํ์ด์ค์ @Transactional ์ฌ์ฉ์ ๊ถ์ฅํ๋. ์คํ๋ง์ ํ๋ก์๋ฐฉ์์ด ์๋๋ผ๋ฉด ๋ฌด์๊ฐ ๋๋ค.. ์ด๋ด๋๋ ๊ตฌํํด๋์ค(ํ๊น)์ ๋ช ์ํด์ผํ๋ค. ๊ทธ๋ฐ๋ฐ ์ด๋ด ๊ฒฝ์ฐ ๊ตฌํํด๋์ค๋ง๋ค ๋ช ์ํด์ผํ๋
์ค๋ณต์ฑ
์ด ๋ํ๋๊ฒ ๋๋ ๋จ์ ์ด ์๊ธฐ๋ํ๋ค.
ํธ๋์ญ์ ์ ๋ ธํ ์ด์ ์ ์ฌ์ฉ์ ์ํ ์ค์
์ด๋ ธํ ์ด์ ์ฌ์ฉ์ xml ์ค์ ์ ๊ด๋ จ ์ฌ์ฉ์ฌ๋ถ ๋ช ์ ํ์
ํธ๋์ญ์
์ด๋
ธํ
์ด์
์ ์ฉ
ํธ๋์ญ์ ์๋ ๊ฒฝ์ฐ DAO์์ ์์ธ๋ฅผ ๋ฐ์์ํค๊ธฐ๋ ํ๋ค. JDBC๋ -> ํธ๋์ญ์ ์ด ์์ด๋ ์คํ ๋จ
6.8 ํธ๋์ญ์
์ง์ ํ
์คํธ
์ ์ธ์ ํธ๋์ญ์
๊ณผ ํธ๋์ญ์
์ ํ ์์ฑ
A ๋ฉ์๋์์ ์์๋ ํธ๋์ญ์ .. B๊ฐ A์์ ํธ์ถ๋๋ค๋ฉด ์ ํ ์์ฑ์ ๋ฐ๋ผ A๋ B์ ํธ๋์ญ์ ๋จ์์ ์ผ๋ถ๋ก ํตํฉ์ด ๋๋ค. ์ด๋ฐ ํธ๋์ญ์ ๊ฒฝ๊ณ์ค์ ๊ณผ ์ ํ์ ์ํด ํธ๋์ญ์ ๊ด๋ฆฌ๊ฐ ์ด๋ฃจ์ด์ง๊ฒ ๋จ
์ ์ธ์ ํธ๋์ญ์
AOP๋ฅผ ์ด์ฉํ์ฌ ์ฝ๋ ์ธ๋ถ์์ ํธ๋์ญ์ ๊ธฐ๋ฅ์ ๋ถ์ฌํด์ฃผ๊ณ , ์์ฑ์ ์ง์ ํ ์ ์๊ฒ ํ๋ ๋ฐฉ๋ฒ
ํธ๋์ญ์
๋๊ธฐํ์ ํ
์คํธ
ํธ๋์ญ์ ์ถ์ํ, AOP ๋ฑ์ ๊ธฐ์ ์ด ์์๊ธฐ์ ๊ฐ๋ฅ -> ์ ์ธ์ ํธ๋์ญ์ , ํธ๋์ญ์ ์ ํ
ํธ๋์ญ์ ์ ์ถ์ํ ํต์ฌ๊ธฐ์ 1. ํธ๋์ญ์ ๋งค๋์
PlatformTransactionManager ->
์ผ๊ด๋ ํธ๋์ญ์ ์ ์ด
,ํธ๋์ญ์ ์ฐธ์ฌ
ํธ๋์ญ์ ๋๊ธฐํ
ํธ๋์ญ์ ์ ํ๊ฐ ๊ฐ๋ฅํ ์ด์
ํธ๋์ญ์ ์ ๋ณด๋ฅผ ์ ์ฅํด๋๋
์ ์ฅ์ ์ญํ
ํ ์คํธ๋ฅผ ํ ๋ ํธ๋์ญ์ ์ ๊ฒฝ๊ณ์ค์ (์์)๊ณผ ํธ๋์ญ์ ์ ํ ์์ฑ์ ํตํด ๋กค๋ฐฑ ๋ฐ ์ปค๋ฐ๋ฑ ์์ ์ ์ฉ
ํ์ด๋ฒ๋ค์ดํธ, JPA ๊ฐ์ ORM๋ฑ์ ์ํฐํฐ ํ ์คํธ ํ ๋๋ ์ ์ฉ / ์ฌ๋ฌ ๋ฉ์๋๋ฅผ ์กฐํฉํด์ ์ฌ์ฉํ ๋๋ ์ ์ฉ
ํธ๋์ญ์ ์ ์ ์ดํ์ฌ ํ ์คํธ๋กค๋ฐฑ ๋ฑ ๋ค์ํ๊ฒ ์์ฉ์ ํ ์ ์๋ค!
-> ํ ์คํธ ๋ด์ ๋ชจ๋ DB ์์ ์ ํ๋์ ํธ๋์ญ์ ์์ ๋๊ณ
ํ ์คํธ๊ฐ ๋๋๋ฉด ๋กค๋ฐฑ์ ํด๋ฒ๋ฆฌ๋ ํ ์คํธ
!
ํ
์คํธ๋ฅผ ์ํ ํธ๋์ญ์
์ด๋
ธํ
์ด์
ํ
์คํธ์๋ @Transactional
์ ์ ์ฉ ํ ์ ์์
@ContextConfiguration
-> ์คํ๋ง์ปจํ
์ด๋๋ฅผ ์ด๊ธฐํ ํด์ค
@Transactional
ํ ์คํธ ํด๋์ค์ ๋ถ์ด๋ฉด, ํ๊น ํด๋์ค๋ ์ธํฐํ์ด์ค ์ ์ฉ ๋ ๊ฒ์ฒ๋ผ
ํ ์คํธ๋ฉ์๋์ ํธ๋์ญ์ ๊ฒฝ๊ณ๊ฐ ์๋ ์ค์
๋จํ ์คํธ ๋ด์ ์ ์งํํ๋
๋ชจ๋ ํธ๋์ญ์ ๊ด๋ จ ์์ ์ ํ๋๋ก ๋ฌถ์!
@Rollback
@Transactional ์ ๋กค๋ฐฑ์ ๋ด์ผ๋ ค๊ณ ๋ง๋ ์ด๋ ธํ ์ด์ ์ ์๋๋ค. ๋ฐ๋ผ์
๋กค๋ฐฑ์ ์ด๋ @Rollback
์ ํตํด ์ค์ ๋ฉ์๋ ๋ ๋ฒจ์๋ง ์ ์ฉ ๊ฐ๋ฅ
@TransactionConfiguration
(depreacted)
ํด๋์ค๋ ๋ฒจ์์ ๊ณตํต ์์ฑ ์ ์๊ฐ๋ฅ
ํธ๋์ญ์ ํ ์คํธ์ ๋นํธ๋์ญ์ ํ ์คํธ๋ฅผ ๊ตฌ๋ถํ์ฌ ํด๋์ค๋ฅผ ๋ง๋ค์ด์ ํ ์คํธ ์ํํ๊ธฐ๋ฅผ ๊ถ์ฅ
propagation=Propagation.NEVER ->
ํธ๋์ญ์ ์์์ํจ
ํจ๊ณผ์ ์ธ DB ํ
์คํธ
ํ
์คํธ๋ ์๋ก ๋
๋ฆฝ์ ์ผ๋ก ๊ตฌํ
DB ์ ๊ทผ์์๋ @Transactional์ ํตํ ํธ๋์ญ์
์ค์ ๊ณผ ๋กง๋ฐฑํ
์คํธ ํ์ฉ
์ฝ๋๊ฐ ๋ฐ๋์ง ์๋ ํ ํ
์คํธ ์์๊ฐ ๋ฐ๊ปด๋ ์ผ์ ํ ๊ฒฐ๊ณผ๋ฅผ ๋ผ ์ ์๋๋ก ์์ฑํด์ผ ํ๋ค
๋กค๋ฐฑํ
์คํธ๋
์์ฃผ ์ ์ฉํ๊ฒ ์์ฉ ๋ ๊ฒ์!! ๊ตฟ๊ตฟ ํนํ ๋จ์ํ
์คํธ์์
Last updated