[DB] TRANSCATION PROPAGATION, ISOLATION, 선언적 트랜잭션

이정환·2023년 7월 25일

[CS] DATABASE

목록 보기
17/21

- 트랜잭션 = 온전히 실행하는 하나의 명령단위

  • ==스프링에서 트랜잭션은 인터페이스로 구현체만들어서 쓸수있지만, 주로사용한것은 AOP를 이용한 선언적 트랜잭션 곧, @transactional 을 주로 사용합니다. 분산 디비 시스템 사용시 주로 프로파게이션 사용하고, 또한 여러 트랜잭션 간 읽기 기능 제한하는 고립 옵션도 있습니다. 리드온리, 타임아웃, 롤백포, 노 롤백 포 등이 있습니다.
    • jdbctemplate, jpa, hibernate 등 트랜잭션 사용방법을 보다 추상화시키면서 발전했고, 스프링 트랜잭션은 AOP로 만든 @transactional로 트랜잭션 사용 가능
    • 타입
      • 인터페이스를 구현해서 사용
        • platformTransactionManager 인터페이스(스프링) (겟트랜잭션, 롤백, 커밋 메소드)
        • 구현체
          • dataSourceTransactionManager - Jdbc → 하나의 디비 or 로컬 트랜잭션
          • JpaTransactionManager - jpa → 하나의 디비 or 로컬 트랜잭션
          • JtaTransactionManager - → 두개이상의 데이터베이스 or 글로벌 트랜잭션 - 여러 디비 트랜잭션작업을 하나로 묶기가능

            선언적트랜잭션

      • AOP를 이용한 선언적 트랜잭션
        • tx namespage(xml)

        • @transactional (메서드, 클래스, 인터페이스) - 클래스에 달면 모든 메소드 적용. 클 메 붙으면 메 우선순위

          프로파게이션

          • ==프로파게이션은 required, supports, mandatory, requires_new, not_supported, nested, never 가 있습니다
          • 트랜잭션 메니저 속성 지정 가능 (*transactional 인터페이스 코드 까면 사용가능 속성확인가능)
          • 전파(propagation) - 프로파게이션은 한 비즈니스코드에서 여러개의 DB에 대한 엔티티매니저들을 사용하고 그들이 트랜잭션쓸때 필요개념.
            • REQUIRED (defauilt) - 기존의 트랜잭션이 있으면 그것에 참여해서 하나의 트랜잭션으로 동작, 없으면 새로시작. 문제있으면 롤백
            • SUPPORTS - 기존의 트랜잭션이 있으면 그것에 참여해서 하나의 트랜잭션으로 동작, 그렇지 않으면 트랜잭션 없이 진행.
            • MANDATORY - 기존의 트랜잭션이 있으면 그것에 참여해서 하나의 트랜잭션으로 동작, 그렇지 않으면 예외(혼자 트랜잭션 시작못함)
            • REQUIRES_NEW - 이미 시작된 프랜잭션이 있으면 보류하고, 자신의 메서드 트랜잭션으로 시작
            • NOT_SUPPORTED - 이미 시작된 프랜잭션이 있으면 보류하고, 자신의 메서드를 트랜잭션없이 시작
            • NESTED - 이미 진행중인 트랜잭션 있으면 그 안에 메서드2 넣어서 중첩된 트랜잭션으로 실행, 부모트랜잭션 커밋 롤백에 영향받음(자신은 부모에게 영향못줌)
            • NEVER - 트랜잭션 없으면 자신의 메서드 실행, 이미 존재하는 트랜잭션있다면 예외 발생시킨다

            아이솔레이션

          • 고립(isolation), - 동시 여러 트랜잭션이 진행될때 다른 트랜잭션 내용 참조 유무 (분산이든 아니든), 아래로 내려갈수록 격리수준 상승
            • == 트랜잭션 격리수준은 read uncommitted, read committed, repeatable read, serializable 이 있습니다.
            • READ_UNCOMMITTED - 아직 커밋되지 않은 데이터를 다른 트랜잭션이 참조가능. 트2 가 트1의 데이터를 읽엇는데 트1이 롤백되었을때 트2는 없는 값을 읽어오게됌
            • READ_COMMITTED - 커밋 된 내용만 참조가능. 하지만 한 메서드 내 트2가 트1 후 A 읽고, 트2가 트3 후 A를 읽엇을때 A가 다를 수 있는 문제발생.
            • REPEATABLE_READ - 하나의 트랜잭션이 읽은 로우를 다른 트랜잭션이 수정할 수 없게함, 트랜잭션 진입 이전 커밋만 참조가능. 하지만 트2가 트1의 row 읽엇는데, 트3이 트1에 값을 추가해서 나중에 트2가 다시 값 읽었을때 다른 row가 오게됌
            • SERIALIZABLE - 위 REPEATABLE_READ 문제 해결. 시작된 트랜잭션 참조 자체 불가. 트랜잭션을 순차적으로 실행하는 것과 다를바 없음. 성능이 매우 떨어짐.
            • 낮은 격리단계 선택시 발생 문제
              1. Dirty Read: 커밋되지 않은 데이터를 읽을 수 있어 일관성이 없는 결과가 반환될 수 있습니다.
              2. Non-Repeatable Read: 같은 쿼리를 반복 실행할 때, 다른 트랜잭션이 중간에 데이터를 변경하여 결과가 달라질 수 있습니다.
              3. Phantom Read: 같은 쿼리를 반복 실행할 때, 다른 트랜잭션이 중간에 데이터를 삽입 또는 삭제하여 결과가 달라질 수 있습니다.
          • read-only - 트랜잭션 내에서 update, insert, delete 방지, jpa 더티체킹 기능 무시, 성능향상에 도움. 기본값 false
          • timeout - 트랜잭션 수행하는 제한시간을 설정할 수 있음, 기본옵션에 제한시간 없음. 초단위, 시간지나면 롤백
          • rollback-for - 기본적으로 RuntimeException시 콜백, 체크 예외지만 콜백 대상으로 삼고 싶다면 사용
          • no-rollback-for - 위와 반대로 예외발생해도 롤백안해도될 대상 지정가능.

0개의 댓글