본문 바로가기
Java & 스프링

[Spring] 트랜잭션 전파 알아보기, @Transaction, propagation

by hjhello423 2020. 12. 15.

트랜잭션 전파에 대해 간단하게 정리해보려 합니다.
상세 설명은 다른 블로그를 같이 참조해 주세요.
트랜잭션의 전파에 대해 알아보기 전에 우선 스프링의 트랜잭션에 대해 간단하게 정리해 보겠습니다.

 


@Transaction?

@Transaction은 스프링의 AOP를 이용하여 개발자가 편하게 DB 관련 작업을 할 수 있도록 도와줍니다.
JPA, Mybatis 등을 사용하지 않을 때, 만약 Datasource를 이용해서 개발할 경우 getConnection(), close()를 하나하나 처리해주어야 합니다.

대략 아래와 같은 모습이겠죠.

public class QueryExam {
	
    private static final String QUERY = "select count(*) from ANIMAL";
    
    private DataSource dataSource;

	public QueryExam(DataSource dataSource) {
		this.dataSource = dataSource;
	}

	public void query() {
		Connection conn = null;
        
		try {
			conn = dataSource.getConnection();
			try (Statement stmt = conn.createStatement(QUERY);
					ResultSet rs = stmt.executeQuery()) {
				rs.next();
				return rs.getInt(1);
			}
		} catch (SQLException e) {
			throw new RuntimeException(e);
		} finally {
			if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                }
            }
        }
    }
}

벌써 보기만 해도 복잡한 코드가 나왔습니다.

위 코드를 보면 getConnection(), close() 같은 로직은 모든 DB 접근 로직에서 공통으로 처리해야 하는 부분입니다.
그래서 스프링에서는 이 부분을 AOP를 이용하여 간단하게 개발 가능하도록 해주고 있습니다.
@Transaction을 이용해서요.

그리고 DB의 기본 개념인 ACID를 지원(?) 해 줍니다. (위키 링크)

  • Atomicity(원자성) : 각 트랜잭션이 성공/실패하는 단일 단위로 처리되도록 보장한다.
  • Consistency(일관성) : 모든 데이터는 규칙에 맞는 일관성을 보장한다. (제약조건, 트리거 등의 모든 규칙에 유효해야 한다)
  • Isolation(고립성) : 트랜잭션은 다은 트랜잭션의 영향을 받지 않는다.
  • Durability(지속성) : 트랜잭션이 성공하면 그 결과는 영구적으로 저장된다.

 


트랜잭션 전파(propagation)

트랜잭션 전파는 어떤 트랜잭션이 동작중인 과정에서 다른 트랜잭션을 실행할 경우 '어떻게 처리하는가'에 대한 개념입니다.
아래 간단한 코드를 만들어 봤습니다.

public class Service1 {

	private Service2 service2;
    
	@Transaction
	public void workAnything1() {
    	service2.workAnything2();	
    }
}

public class Service2 {

	@Transaction
	public void workAnything2() {
    	doAnything();
    }
}

workAnything1(), workAnything2() 모두 @Transaction을 선언했습니다.
만약 Service1#workAnything()을 실행한다면 Service2#workAnything2()의 트랜잭션은 어떻게 될까요?

이 부분에 대해 처리해주는 것이 트랜잭션 전파입니다.
그리고 이 전파는 @Transaction의 propagation 속성을 통해 설정하게 됩니다.

value desc
REQUIRED 기본값, tx을 항상 필요로 한다.
진행중인 tx이 있으면 해당 tx을 사용, 없다면 새로운 tx을 생

MANDATORY tx를 필요로 한다.
진행중인 tx가 없을경우 exception을 발생 시킨다.
REQUIRES_NEW 항상 새로운 tx를 생성 한다.
진행중인 tx가 있다면 중지하고 새로운 tx를 시작한다.
새로운 tx가 종료되면 기존의 tx가 다시 동작 한다.
SUPPORTS tx를 필요로 하지 않는다.
만약 진행중인 tx가 있다면 사용한다.
NOT_SUPPORTS tx를 필요로 하지 않는다.
진행중인 tx가 있다면 중지하고 메서드가 종료된 후에 중지했던 tx를 다시 시작한다.
NEVER tx를 필요로 하지 않는다.
진행중인 tx가 있다면 exception을 발생 시킨다.
NESTED 진행중인 tx가 있다면 기존 tx에 중첩된 tx에서 메서드를 실행한다.

 


Isolation

propagation에 대해 정리한 김에 @Transaction의 isolation 속성에 대한 설정에 대해서도 정리해 보겠습니다.

value desc
DEFAULT 기본 설정값 사용.
READ_UNCOMMITTED 다른 tx가 commit하지 않은 데이터를 읽을 수 있다.
READ_COMMITTED 다른 tx가 commit한 데이터를 읽을 수 있다
REPEATABLE_READ 처음 읽은 데이터와 두번째 읽은 데이터가 동일한 값을 같는다.
SERIALIZABLE 동일한 데이터에 대해 2개 이상의 tx가 동시에 수행될 수 없다.

 


참조

위키 ACID : en.wikipedia.org/wiki/ACID

 

반응형

댓글