@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 문제 해결. 시작된 트랜잭션 참조 자체 불가. 트랜잭션을 순차적으로 실행하는 것과 다를바 없음. 성능이 매우 떨어짐.
- 낮은 격리단계 선택시 발생 문제
- Dirty Read: 커밋되지 않은 데이터를 읽을 수 있어 일관성이 없는 결과가 반환될 수 있습니다.
- Non-Repeatable Read: 같은 쿼리를 반복 실행할 때, 다른 트랜잭션이 중간에 데이터를 변경하여 결과가 달라질 수 있습니다.
- Phantom Read: 같은 쿼리를 반복 실행할 때, 다른 트랜잭션이 중간에 데이터를 삽입 또는 삭제하여 결과가 달라질 수 있습니다.
- read-only - 트랜잭션 내에서 update, insert, delete 방지, jpa 더티체킹 기능 무시, 성능향상에 도움. 기본값 false
- timeout - 트랜잭션 수행하는 제한시간을 설정할 수 있음, 기본옵션에 제한시간 없음. 초단위, 시간지나면 롤백
- rollback-for - 기본적으로 RuntimeException시 콜백, 체크 예외지만 콜백 대상으로 삼고 싶다면 사용
- no-rollback-for - 위와 반대로 예외발생해도 롤백안해도될 대상 지정가능.