2016년 5월 3일 화요일

Spring Transaction의 Propagation과 Isolation에 대해..

참고 : http://stackoverflow.com/questions/8490852/spring-transactional-isolation-propagation , http://www.byteslounge.com/tutorials/spring-transaction-propagation-tutorial , http://www.byteslounge.com/tutorials/spring-transaction-isolation-tutorial

헷갈릴 땐 라이브러리의 소스코드의 각 타입별 주석을 참고해도 되지만 이참에 정리하자 싶어서 작성합니다. Transactional 어노테이션의 propagation과 isolation 항목에 대한 설정 정보에 대해 알아보도록 하겠습니다.

PROPAGATION

비지니스 메소드가 호출될 때 자기 자신과 내부에서 호출 된 Transaction(이하 tx)간에 어떻게 상호 작용할 것인지에 대한 상태를 정의 하는 항목으로 다음과 같은 설정들이 존재 합니다.
  • REQUIRED : 해당 상태가 선언된 메소드가 실행 될 때 tx가 존재 한다면 공유해서 사용하고 그렇지 않다면 새 tx를 생성해서 사용합니다. 만약 내부에서 호출 된 메소드가 자신과 마찬가지로 REQUIRED가 선언된 상태라면 자신과 내부 tx각각은 논리적으로는 구분 되지만 물리적으로는 하나의 tx가 됩니다. 내부에서 호출 된 메소드의 tx가 롤백 된다면 자신을 포함한 물리적인 하나의 tx가 롤백 되는 구조를 만들 수 있습니다.
  • REQUIRES_NEW : 해당 상태가 선언된 메소드가 실행될 때 항상 새로운 물리적인 tx를 생성하고 해당 tx가 롤백 된다고해서 물리적으로 분리된 다른 tx가 롤백 되지는 않습니다. 만약 내부적으로 새로운 tx가 시작 된다면 자신의 tx는 잠시 정지 되었다가 내부 tx가 종료된 시점에 이어서 수행되게 됩니다.
  • NESTED : 자신과 내부 tx들이 하나의 물리적인 tx를 사용하지만 내부에서 호출된 NESTED tx들에 savepoint를 세팅하는 형태 입니다. 그렇기 때문에 내부의 NESTED tx중 하나가 롤백이 된다고 하더라도 자신이 롤백 되지는 않습니다. 이 기능은 JDBC savepoint를 통해 구현되기 때문에 Spring JDBC로 관리되는 tx를 사용할때만 써야 합니다.
  • MANDATORY : 해당 상태가 호출될 때 열려있는 tx가 반드시 존재해야하며 그렇지 않으면 컨테이너에서 예외를 던집니다.
  • NEVER : 해당 상태가 호출될 때 열려있는 tx가 반드시 존재하지 않아야 하며 그렇지 않으면 컨테이너에서 예외를 던집니다.
  • NOT_SUPPORTED : 해당 상태는 tx의 범위에 포함되지 않는 것을 수행합니다. 만약 열려있는 tx가 존재 한다면 해당 tx를 잠시 멈추고 작업을 수행합니다.
  • SUPPORTS : 열려있는 tx가 이미 존재한다면 해당 tx에 포함되어 수행되며 만약 열려있는 tx가 존재하지 않더라도 수행은 되지만 tx와 관계없이 처리 됩니다.
주의할 점들..
  • 기본적으로 tx을 롤백 상태로 만들기 위해서는 unchecked exceptions를 필요로 하며 checked exceptions를 이용하기 위해서는 별도의 설정이 필요합니다.
  • Transactional 어노테이션만 선언된 메소드(Declarative transactions)에서 동일한 Bean 내부의 다른 메소드를 직접 호출할 경우(Self-invocation) 컨테이너에 의해 Transactional 선언이 무시되기 때문에 이경우는 aspectj를 사용해서 구성해야 합니다.
ISOLATION

ACID tx 요소 중 isolation 레벨에 대한 설정으로 특정 위치의 데이터에 대해 동시 다수의 tx가 존재 할 때 해당 데이터에 어떻게 접근할 것인지에 대해 정의할 수 있습니다.
  • READ_UNCOMMITTED : 여러 tx가 동시에 x라는 데이터에 접근 할 때 x에 변경이 일어난 시점과 읽는 시점에 따라 롤백 여부와 상관없이 변경된 값을 읽는 더티 리드(dirty reads)를 허용하는 상태입니다.
  • READ_COMMITTED : 더티 리드의 문제는 없지만 동시에 x라는 데이터에 접근할 때 타임라인 상 A라는 tx에서 x를 읽은 후 tx가 종료 되기 전에 B라는 tx에서 x를 변경후 커밋을 하게 될 경우 A에서 x를 다시 읽는 케이스가 존재 한다면 처음 읽은 x의 값과 나중에 읽은 x의 값이 다른 문제(non-repeatable reads)가 발생하게 됩니다.
  • REPEATABLE_READ : 하나의 tx에서 단일 레코드를 여러번 읽는 경우 결과가 항상 같아야 하는 상태이며 dirty reads와 non-repeatable reads 문제를 제거할 수 있습니다. 하지만 범위 스캔을 하는 경우 tx A에서 범위의 조건이 0-20 사이의 값을 읽고 tx A가 종료되기 전에 tx B에서 0-20사이에 레코드를 추가하게 된다면 tx A에서 0-20 사이의 값을 다시 읽었을 때 tx B에서 추가한 레코드(phantom records)가 포함되는 팬텀 리드(phantom reads)의 문제가 있습니다.
  • SERIALIZABLE : 가장 제한적인 상태이며 읽기, 범위 스캔, 쓰기에 tx락을 거는 형태입니다. 앞서 언급한 모든 문제를 해결할 수 있지만 tx의 동시성을 허용하지 않아 퍼포먼스 패널티를 지속적으로 증가시키는 문제가 있습니다.
  • DEFAULT : DBMS에서 정의된 Default Isolation 레벨에 대한 상태를 적용합니다.
각 isolation 레벨이 갖는 문제를 요약하면 다음과 같습니다.
  • READ_UNCOMMITTED : dirty reads, non-repeatable reads, phantom reads
  • READ_COMMITTED : non-repeatable reads, phantom reads
  • REPEATABLE_READ : phantom reads

2016년 5월 1일 일요일

4월 4주차 소식들..

보안

인기있는 업무용 메신저인 Slack의 보안 토큰을 Github과 같은 공개된 저장소에 올려서 보안위험에 노출된 경우가 많아 Slack측에서 발견된 토큰을 폐기하고 발행자와 관련 팀 담당자에게 연락을 하고 있다고.. 주로 봇 통합 용도로 많이 사용된 것 같다는데 보안 토큰을 공개된 장소에 공유하는 건 좀.. 음.... 링크

소프트웨어

Node.js 의 6.0 버전 소식.. 5.0과 다르게 10월부터 LTS 지원을 할 예정이라고.. 추가로 ECMAScript 2015 지원 정보 챠트.. 링크 링크

Linux의 /dev/random LRNG 패치에 대한 이야기.. 기존 방식과 차이점으로 가상화 환경이나 SSD를 사용하는 환경에서도 부트 타임에 충분한 엔트로피를 제공하고 대규모 병렬 시스템에서 엔트로피 수집에 대한 충격을 제한하며 /dev/urandom과 get_random_bytes에서의 큰 성능 향상등이 고려되고 있다고.. 링크
 
Nginx 1.10 Stable 버전이 발표 되었다는 소식.. 스트림 모듈, HTTP/2, 다이나믹 모듈 지원등이 특징이라고.. 링크


기타

특허 트롤에 대응하기 위한 시스템에 대한 소식.. 미국의 발행되거나 출판된 특허에 대한 공개정보를 마이닝 해서 앞으로 나올만한 가능성이 있는 특허 정보를 조합해서 사전에 공개하는 All Prior Art 라는 시스템에 대한 이야기가.. 링크 링크

하드웨어

구글 OnHub 라우터의 IFTTT 지원 소식.. IoT와 홈오토메이션의 중심이 되지 않을까 추측은 했었는데 IFTTT를 지원하게 될 줄은... 영상 링크를 보는편이 어떤게 가능해 지는지 바로 와닿을 듯한.. 링크

AMD의 서버관련 x86과 SoC 관련 IP의 중국 라이선싱 소식.. THATIC이라는 조인트 벤처인데 중국이 반도체 관련 사업에 꽤 적극적인 모습을 보이고 있어서 어떤 형태로 칩이 나오게 될지는 모르겠지만 중국내 FAB육성과 함께 자국내 IT기업들이 서버에 사용할 제품을 만들려는 것 같아보이는데 Intel과의 라이선스 문제는 없다고 그러고 Intel에겐 새로운 경쟁자가 추가되는 상황이라 탐탁치는 않을 듯... 링크