Transaction
μ€νλ§μμλ λκ°μ§μ νΈλμμ λ°©λ²μ μ¬μ©νλ€.
첫λ²μ§Έλ μ μΈμ μν μ μΈμ νΈλμμ μ΄λ€.
λλ²μ§Έλ νλ‘κ·Έλ¨μ μν νΈλμμ μ΄λ€.
νλ‘κ·Έλ¨μ μν νΈλμμ
μ try ~ catch
ꡬ문μ μ¬μ©νμ¬ μ»€λ°κ³Ό λ‘€λ°±μ μ΄μ©νμ¬ νΈλμμ
μ μ²λ¦¬νλ€.
μ μΈμ νΈλμμ μ AOPλ₯Ό μ΄μ©νλ λ°©μκ³Ό μ΄λ Έν μ΄μ μ μ΄μ©νλ λ°©μμ΄ μλ€.
AOP λ₯Ό μ΄μ©ν μ μΈμ νΈλμμ
context-datasource.xml
μ λ΄μ©μ μμ
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd ">
β¦ μλ΅ β¦
<!-- Transaction Manager -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="get*" read-only="true" />
<tx:method name="delete*" />
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="transactionPointcut" expression="execution(* com.syaku.bbs.dao.BbsDao.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="transactionPointcut" />
</aop:config>
<bean id="bbsDao" class="com.syaku.bbs.dao.BbsDao"/>
</beans>
transactionManager
μμλ dataSource μ μλ₯Ό μ°Έμ‘°νλ€.
κΈ°μ‘΄ jdbc λ‘κ·Έλ₯Ό μΆλ ₯νκΈ° μν΄ μμ±ν dataSource λ₯Ό μ°Έμ‘°νλ€.
λ§μ½ λ‘κ·Έκ° μλ€λ©΄ μ°κ²°μ μν΄ μμ±ν dataSource λ₯Ό μ°Έμ‘°νλ€.
tx
λ μ€νλ§ νΈλμ μ
μ λ΄λΉνλ©° tx
λ₯Ό μ¬μ©νκΈ° μν΄ μλ¨μ λ€μμ€νμ΄μ€λ₯Ό μΆκ°νμλ€.
<tx:method>
μμ±
μμ±λͺ | μν |
---|---|
name | νΈλμμ
μ΄ μ μ©λ λ©μλ μ΄λ¦μ λͺ
μνλ©° νμ μμ±μ΄λ€.get* delete* * μ΄ μ€μ κ°λ₯νλ€. |
propagation | νΈλμμ
μ μ νλμμ μ€μ νλ€. κΈ°λ³Έκ°μ REQUIRED μ΄λ€.ν΄λΉ μ΅μ μ μλμμ μ€λͺ |
isolation | νΈλμμ
μ 격리 μμ€μ μ€μ νλ€. κΈ°λ³Έκ°μ DEFAULT μ΄λ€.ν΄λΉ μ΅μ μ μλμμ μ€λͺ |
timeout | νΈλμμ
μ μκ° μ΄κ³Όκ°μ μ€μ νλ€. κΈ°λ³Έκ°μ -1 μ΄λ€. |
read-only | μ½κΈ° μ μ© μ¬λΆλ₯Ό μ€μ νλ€. κΈ°λ³Έκ°μ false μ΄λ€. |
rollback-for | λ‘€λ°±ν μμΈλ₯Ό μ€μ νλ€. μ¬λ¬κ°λ₯Ό μ λ ₯ν κ²½μ° μ½€λ§( , ) λ‘ κ΅¬λΆνλ€.κΈ°λ³Έκ°μ RuntimeException μ΄λ€. |
no-rollback-for | λ‘€λ°±νμ§ μμ μμΈλ₯Ό μ€μ νλ€. μ¬λ¬κ°λ₯Ό μ λ ₯ν κ²½μ° μ½€λ§( , ) λ‘ κ΅¬λΆνλ€. |
REQUIRED
)
propagation - μ ν μ΅μ
(κΈ°λ³Έκ° : μμ±κ° | μ€λͺ |
---|---|
REQUIRED | λΆλͺ¨ νΈλμμ λ΄μμ μ€ννλ©° λΆλͺ¨ νΈλμμ μ΄ μμ κ²½μ° μλ‘μ΄ νΈλμμ μ μμ±νλ€. |
REQUIRES_NEW | λΆλͺ¨ νΈλμμ μ 무μνκ³ λ¬΄μ‘°κ±΄ μλ‘μ΄ νΈλμμ μ΄ μμ±λλ€. |
SUPPORT | λΆλͺ¨ νΈλμμ λ΄μμ μ€ννλ©° λΆλͺ¨ νΈλμμ μ΄ μμ κ²½μ° nontransactionally λ‘ μ€νλλ€. |
MANDATORY | λΆλͺ¨ νΈλμμ λ΄μμ μ€νλλ©° λΆλͺ¨ νΈλμμ μ΄ μμ κ²½μ° μμΈκ° λ°μλλ€. |
NOT_SUPPORT | nontransactionally λ‘ μ€ννλ©° λΆλͺ¨ νΈλμμ λ΄μμ μ€νλ κ²½μ° μΌμ μ μ§λλ€. |
NEVER | nontransactionally λ‘ μ€νλλ©° λΆλͺ¨ νΈλμμ μ΄ μ‘΄μ¬νλ€λ©΄ μμΈκ° λ°ννλ€. |
NESTED | ν΄λΉ λ©μλκ° λΆλͺ¨ νΈλμμ
μμ μ§νλ κ²½μ° λ³κ°λ‘ 컀λ°λκ±°λ λ‘€λ°±λ μ μλ€. λνλ νΈλμμ μ΄ μμ κ²½μ° REQUIRED μ λμΌνκ² μλνλ€. |
DEFAULT
)
isolation - 격리 μμ€ (κΈ°λ³Έκ° : μμ±κ° | μ€λͺ |
---|---|
DEFAULT | DB μμ μ€μ λ κΈ°λ³Έ 격리 μμ€μ λ°λ₯Έλ€. |
SERIALIZABLE | κ°μ₯ λμ 격리μμ€μ κ°μ§λ©° μ¬μ©μ μ±λ₯μ νκ° μμ μ μλ€. |
READ_UNCOMMITTED | 컀λ°λμ§ μλ λ°μ΄ν°μ λν΄μ μ½κΈ°λ₯Ό νμ©νλ€. |
READ_COMMITTED | 컀λ°λ νΈλμμ μ λν΄ μ½κΈ°λ₯Ό νμ©νλ€. |
REPEATABLE_READ | λμΌν νλμ λν λ€μ€ μ κ·Όμ λμΌν κ²°κ³Όλ₯Ό μ»μμ μλ κ²μ 보μ₯νλ€. |
μ°Έκ³ μλ£
Aspectj Expression
<aop:config>
μμ νΈλμμ
μ μ μ©ν λμμ μ€μ νλ€.
* com.syaku.bbs.dao.BbsDao.*(..)
λΌκ³ μ
λ ₯ν λΆλΆμ Aspectj ννμμ΄λΌκ³ νλ€.
execution(
μ κ·Όμ μ΄μ
리ν΄νμ
ν¨ν€μ§
λ©μλμ΄λ¦
(μΈμ
))
*
λͺ¨λλ₯Ό μλ―Έν¨..
0κ° μ΄μμ μλ―Έν¨
Annotation μ μ΄μ©ν μ μΈμ νΈλμμ
AOP λ₯Ό μ΄μ©ν νΈλμμ λ³΄λ€ λ κ°κ²°νκ² μ²λ¦¬ κ°λ₯ν λ°©μ
μ΄μ μ AOP λ₯Ό μ΄μ©ν μ μΈμ νΈλμμ λ°©μμ μ€μ μ λͺ¨λ μ κ±° νΉμ μ£Όμ μ²λ¦¬νλ€.
λ¨. bean transactionManager λ λ¨κ²¨λλ€.
context-datasource.xml
μμ
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd ">
<bean id="jdbcProp" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:jdbc.properties" />
</bean>
<bean id="dataSourceSpied" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<bean id="dataSource" class="net.sf.log4jdbc.Log4jdbcProxyDataSource">
<constructor-arg ref="dataSourceSpied" />
<property name="logFormatter">
<bean class="net.sf.log4jdbc.tools.Log4JdbcCustomFormatter">
<property name="loggingType" value="MULTI_LINE" />
<property name="sqlPrefix" value="SQL:::" />
</bean>
</property>
</bean>
<!-- Transaction Manager -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
</beans>
μμ± | μ΄λ Έν μ΄μ μ¬μ© |
---|---|
isolation | @Transactional(isolation=Isolation.DEFAULT |
noRollbackFor | @Transactional(noRollbackFor=NoRoleBackTx.class) |
noRollbackForClassName | @Transactional(noRollbackForClassName="NoRoleBackTxβ) |
propagation | @Transactional(propagation=Propagation.REQUIRED) |
readOnly | @Transactional(readOnly = true) |
rollbackFor | @Transactional(rollbackFor=RoleBackTx.class) |
rollbackForClassName | @Transactional(rollbackForClassName="RoleBackTxβ) |
timeout | @Transactional(timeout=10) |
BBSDao μ νΈλμμ μ μν΄ μ΄λ Έν μ΄μ μ μΆκ°νμλ€.
package com.syaku.bbs.dao;
import java.util.*;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service(value = "bbsDao")
@Transactional(readOnly=true)
public class BbsDao {
@Resource=(name = "bbsMapper")
private BbsMapper bbsMapper;
public List<BbsVo> getSelect(Map map) {
return this.bbsMapper.select(map);
}
public void insert(BbsVo bbsVo) {
this.bbsMapper.insert(bbsVo);
}
public void update(BbsVo bbsVo) {
this.bbsMapper.update(bbsVo);
}
@Transactional
public void delete(int idx) {
this.bbsMapper.delete(idx);
throw new RuntimeException("κ°μ λ‘ μ€λ₯λ₯Ό λ°μ μμΌλ΄ !! ");
}
}
ν μ€νΈλ‘ κΈμ μμ ν΄λ³΄λ©΄ μμ λμ§ μλλ€
μ€νλ§ νΈλμμ μ @Service μ μ μ©νλ κ²μ΄ λ°λμ§νλ€.
νλ‘κ·Έλ¨μ μν νΈλμμ
νλ‘κ·Έλ¨μ μν νΈλμμ
μ try ~ catch
λ¬Έμ μ¬μ©νμ¬ μμ±νλ€.
context-datasource.xml
μ νκΈ°μ κ°μ΄ μμ νλ€.
<!-- Transaction Manager -->
<bean id="" class="">
<property name="dataSource" ref="dataSource">
</bean>
@Resource(name = "transactionManager")
protected DataSourceTransactionManager txManager;
public void insert(BbsVo bbsVo) {
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus txStatus = txManager.getTransaction(def);
try {
this.bbsMapper.insert(bbsVo);
int a = 1 / 0;
txManager.commit(txStatus);
} catch(Exception e) {
txManager.rollback(txStatus);
throw new Exception(e.getMessage());
}
}
μμ @Controller
μμ€
try {
if (idx == null || idx == 0) {
this.bbsDao.insert(bbsVo);
xml.setMessage("μΆκ°λμμ΅λλ€.");
xml.setError(false);
} else {
this.bbsDao.update(bbsVo);
xml.setMessage("μμ λμμ΅λλ€.");
xml.setError(false);
}
} catch (Exception e) {
xml.setMessage(e.getMessage());
xml.setError(true);
}
β ResolvableType lombok β