Spring AOP _ 트랜잭션

dwanGim·2022년 6월 28일
0

spring_basic

목록 보기
23/41

트랜잭션

AOP를 이용해 트랜잭션을 이해하고 적용해볼 수 있습니다.

트랜잭션은 2개 이상의 쿼리문을 함께 실행하는 프로그래밍 개념입니다.

트랜잭션에서 함께 실행되는 쿼리문들은 모두 함께 성공하거나

실패해야 합니다.

위 표의 4가지 원칙에 따라 기능을 묶으면 트랜잭션을 잘 사용할 수 있습니다.

root- context 내부에 transactionManager를 bean을 생성하고

의존성 주입을 했습니다.

namespace에서 필요한 이름에 체크를 해줍니다.

그럼 이제 트랜잭션을 시험해볼 두 개의 테이블을 만듭니다.

두 테이블의 컬럼 길이가 달라서 5 문자 이상의 insert문을

실행시켜 서로 충돌이 나도록 해보겠습니다.

트랜잭션이 필요할 때 -> 예시

다음과 같이 Sample1Mapper 와 Sample2Mapper를 생성하고

service를 생성합니다.

mapper xml은 귀찮으니까 따로 작성하지 않고 어노테이션으로

구문을 작성해보겠습니다.

// Sample1Mapper

package com.ict.mapper;

import org.apache.ibatis.annotations.Insert;

public interface Sample1Mapper {

	@Insert("insert into tbl_test1 (col1) values (#{data})")
	public int insertCol1(String data);
	
}
// Sample2Mapper

package com.ict.mapper;

import org.apache.ibatis.annotations.Insert;

public interface Sample2Mapper {

	@Insert("insert into tbl_test2 (col2) values (#{data})")
	public int insertCol2(String data);
}

아래는 service입니다.

// SampleTxService

package com.ict.service;

public interface SampleTxService {

	public void addData(String value);
}
package com.ict.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.ict.mapper.Sample1Mapper;
import com.ict.mapper.Sample2Mapper;

import lombok.extern.log4j.Log4j;

@Log4j
@Service
public class SampleTxServiceImpl implements SampleTxService{

	@Autowired
	private Sample1Mapper mapper1;
	
	@Autowired
	private Sample2Mapper mapper2;
	
	@Override
	@Transactional
	public void addData(String value) {
	
		log.info("mapper1..........");
		mapper1.insertCol1(value);
		log.info("mapper2.........");
		mapper2.insertCol2(value);
		
	}

}

바로 위의 SampleTxServiceImpl을 이용해서

addData 메서드를 실행시켜 테스트 1번 테이블에는 값이 들어갈 수 있지만

2번 테이블에는 컬럼 문자 길이가 초과되어 들어가지 못하게 해보았습니다.

@Transactional 어노테이션을 걸어 두 개의 쿼리문을 묶었습니다.

이제 JUnit 테스트를 실행해보아야겠습니다.

알다시피 넣으려는 값이 5글자 이상으로 너무 커서

test_tbl2에는 들어가지 못하고 실패합니다.

원래 이럴 경우에 test_tbl1에는 위의 값이 들어가고

test_tbl2에는 값이 들어가지 못한 채 요청이 끝나게 되었지만

이제는 다릅니다.

두번째 pstmt가 실패했기 때문에 첫번째 pstmt가

.close()로 닫히고 return되는 것을 확인할 수 있습니다.

트랜잭션이 걸려있기 때문에 어느 한쪽에서 에러가 생기면

다른 쿼리문도 실행이 되지 않도록 설정이 된 것 입니다.

이를 이용해서 이제 여러 쿼리문을 복합적으로 처리하면서도

치명적인 DB에러를 피할 수 있게 되었습니다.

profile
배울 게 참 많네요.

0개의 댓글