๐ Spring ํธ๋์ญ์ : ์ค๋ฌด์์ ์ฐ๋ ์ง์ง ๊ฐ๋ ๋ง ์ ๋ฆฌ
๐ธ ํธ๋์ญ์ (Transaction)์ด๋?
• ํ๋์ ์์ ๋จ์๋ฅผ ๋ฌถ๋ ๊ฐ๋
• ์ ๋ถ ์ฑ๊ณตํ๊ฑฐ๋, ์ ๋ถ ์คํจํด์ผ ํจ (์์์ฑ)
• ์ : ๊ณ์ข ์ด์ฒด → ์ถ๊ธ๊ณผ ์ ๊ธ์ด ๋ชจ๋ ์ฑ๊ณตํด์ผ ํจ
๐ธ ํธ๋์ญ์ ์ด ํ์ํ ์ด์
• ๋จ์ CRUD ์์ ์ ๋ฌธ์ ๊ฐ ์์
• ํ์ง๋ง ์ฌ๋ฌ DAO, ์ฌ๋ฌ ์์ ์ด ์ฎ์ธ ๋น์ฆ๋์ค ๋ก์ง์์๋ ์คํจ ์ ์ ์ฒด ์ทจ์๊ฐ ๋์ด์ผ ํจ
• ์ด๋ฅผ AOP ๋ฐฉ์์ผ๋ก ๋ฌถ์ด์ ์ฒ๋ฆฌํจ
๐ธ ํธ๋์ญ์ ์ ์ฉ ์์น
• DAO X (๋จ๊ฑด ๋จ์)
• Service ๊ณ์ธต (๋น์ฆ๋์ค ๋ก์ง) O
• ์ : ์ฌ๋ฌ DAO์ ๋ฉ์๋๋ฅผ ํธ์ถํ๋ ์๋น์ค ๋ฉ์๋
๐ธ ํธ๋์ญ์ ๋งค๋์ ์ข ๋ฅ
ํธ๋์ญ์ ๋งค๋์ ๋ ์ฌ์ฉํ๋ DAO ๋ฐฉ์์ ๋ฐ๋ผ ๋ค๋ฅด๊ฒ ๋ฑ๋ก
DAO ๋ฐฉ์ | ํธ๋์ญ์ ๋งค๋์ Bean ID |
JdbcTemplate | DataSourceTransactionManager |
MyBatis | DataSourceTransactionManager |
JPA/Hibernate | JpaTransactionManager ๋๋ HibernateTransactionManager |
<!-- JdbcTemplate ๋๋ MyBatis์ฉ ํธ๋์ญ์
๋งค๋์ -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
๐ธ ํธ๋์ญ์ AOP ์ ์ฉ
<!-- AOP ํธ๋์ญ์
Advice ์ ์ -->
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="insert*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="delete*" propagation="REQUIRED"/>
<tx:method name="*" read-only="true"/>
</tx:attributes>
</tx:advice>
• name="*": ํด๋น ์ด๋ฆ ํจํด์ ๊ฐ์ง ๋ฉ์๋์ ํธ๋์ญ์ ์ ์ฉ
• propagation="REQUIRED": ๊ธฐ์กด ํธ๋์ญ์ ์ด ์์ผ๋ฉด ์ฐธ์ฌ, ์์ผ๋ฉด ์๋ก ์์ฑ
• read-only="true": ์ฝ๊ธฐ ์ ์ฉ ์ฟผ๋ฆฌ์๋ง ํ์ฉ
๐ธ ํธ๋์ญ์ AOP ์ฐ๊ฒฐ
<aop:config>
<aop:pointcut id="txPointcut" expression="execution(* com.example.service..*Impl.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>
</aop:config>
๐ธ ํต์ฌ
• ํธ๋์ญ์ ์ CRUD์ ๋ถ์ด๋ ๊ฒ ์๋!
• ํธ๋์ญ์ ์ ๋น์ฆ๋์ค ๋ก์ง์ ๋ถ์ด๋ ๊ฒ
• ๋จ์ผ SQL์ DB ๋ ๋ฒจ์์ ์๋ ์ปค๋ฐ/๋กค๋ฐฑ์ด ๋์ง๋ง, ์ฌ๋ฌ ์์ ์ ๋ฌถ์ด์ผ ํจ
• ์ฐ๋ฆฌ๊ฐ AOP๋ก ๋ก๊น ํ ๊ฒ์ฒ๋ผ, ํธ๋์ญ์ ๋ AOP๋ก ๋ฌถ์
๐ง ๋ง๋ฌด๋ฆฌ ์์ฝ
• ํธ๋์ญ์ ์ CRUD ํ๋ํ๋๊ฐ ์๋๋ผ, ๋น์ฆ๋์ค ๋ฉ์๋ ๋จ์์์ ์ ์ฒด๋ฅผ ๋ฌถ์ด์ ์ฒ๋ฆฌํ๋ ๊ฐ๋
• DAO๊ฐ ์๋๋ผ Service์์, @Transactional ๋๋ <tx:advice>๋ก ์ฒ๋ฆฌ