[Spring Boot] 단일 DB 트랜잭션

exoluse·2021년 12월 9일
0

Spring

목록 보기
3/11
post-thumbnail

1. dependency check

<dependency>
	<groupId>org.aspectj</groupId >
	<artifactId>aspectjweaver</artifactId>
</dependency>

2. TransactionConfig 작성

package com.iut.mes.config;

import java.util.Collections;
import java.util.HashMap;

import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource;
import org.springframework.transaction.interceptor.RollbackRuleAttribute;
import org.springframework.transaction.interceptor.RuleBasedTransactionAttribute;
import org.springframework.transaction.interceptor.TransactionAttribute;
import org.springframework.transaction.interceptor.TransactionInterceptor;

@Configuration
public class TransactionConfig {
	
	@Autowired
	PlatformTransactionManager transactionManager;

	@SuppressWarnings("deprecation")
	@Bean
	public TransactionInterceptor transactionAdvice() {
		NameMatchTransactionAttributeSource txAttributeSource = new NameMatchTransactionAttributeSource();
		RuleBasedTransactionAttribute txAttribute = new RuleBasedTransactionAttribute();
		
		txAttribute.setRollbackRules(Collections.singletonList(new RollbackRuleAttribute(Exception.class)));
		txAttribute.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
		
		HashMap<String, TransactionAttribute> txMethods = new HashMap<String, TransactionAttribute>();
		txMethods.put("*", txAttribute);
		txAttributeSource.setNameMap(txMethods);

		return new TransactionInterceptor(transactionManager, txAttributeSource);
	}

	@Bean
	public Advisor transactionAdviceAdvisor() {
		AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
		pointcut.setExpression("execution(* com..mes..service.*Impl.*(..))");
		return new DefaultPointcutAdvisor(pointcut, transactionAdvice());
	}
	
}

3. 서비스에 @Transactional 달기

@Transactional
public void insertAuth() {
	userMapper.insertAuth1();
	userMapper.insertAuth2();
}

4. 테스트는 이렇게

<insert id="insertAuth1" parameterType="hashMap">
	insert into authority (username, authority_name)	
	values ('aaa', 'wwwwwwww2')
</insert>
	
<insert id="insertAuth2" parameterType="hashMap">
	insert into authority (username,authority_namea)	
	values ('aaa', 'wwwwwwww3')
</insert>

5. 결과

뭐 당연한 거겠지만... insertAuth2에서 예외로 빠져서 이미 실행된 insertAuth1 이 롤백되었다.

### Error updating database.  Cause: java.sql.SQLSyntaxErrorException: Unknown column 'authority_namea' in 'field list'
### The error may exist in mapper/user.xml
### The error may involve com.iut.mes.mapper.UserMapper.insertAuth2-Inline
### The error occurred while setting parameters
### SQL: insert into authority   (username,   authority_namea)    values ('aaa', 'wwwwwwww3')
### Cause: java.sql.SQLSyntaxErrorException: Unknown column 'authority_namea' in 'field list'
; bad SQL grammar []; nested exception is java.sql.SQLSyntaxErrorException: Unknown column 'authority_namea' in 'field list'] with root cause

0개의 댓글