트랜잭션은 여러 작업을 1개로 논리적으로 하는 단위
중간에 1개라도 실패하면 초기값으로 돌아가는 Rollback이 있음
모든 작업이 성공해야 성공, 데이터베이스에 커밋된다
Atomicity
: 트랜잭션 내에서 작업들은 하나의 작업처럼 성공하거나 실패
하나라도 실패하면 롤백, 다 성공하면 커밋
Consistency
: 데이터베이스의 규칙에 따르는 가
Isolation ⭐️
: 동시에 실행되는 트랜잭션들이 서로에게 어떠한 영향을 미칠 수 있는 격리 수준을 정한다.
Durability
: 트랜잭션이 끝나면 결과가 항상 DB에 기록되어야한다.
시스템에 문제가 생기더라도 로그를 활용한 성공한 트랜잭션 내용을 복구해야한다.
RuntimeException(또는 하위 클래스) 런타임예외가 발생했을 때만 롤백을 한다.
rollbackFor
: 기존 롤백 정책에 특정 예외를 추가하고 싶을 경우
noRollbackFor
: 기존 롤백 정책에 특정 예외를 제외하고 싶을 경우

하나의 트랜잭션이 이미 진행 중일 때 다른 메서드에서 호출된 트랜잭션이 기존 트랜잭션에 참여할지 아니면 새로운 트랜잭션을 시작할지 설정해 주는 역할을 한다.
1. REQURED ⭐️
: 스프링의 기본 전파 속성
트랜잭션이 있으면 참여, 없으면 새로 시작
2. REQUIRES_NEW ⭐️
: 항상 새로운 트랜잭션 시작
기존 진행은 일단 보류
자식 트랜잭션이 커밋되면 이어서 진행
SUPPORTS
: 기존 트랙잭션이 있다면 참여,
없다면 트랙잭션 없이 진행
NESTED
: 이미 진행중인 트랜잭션이 있다면 중첩 트랜잭션 시작
부모 트랜잭션이 롤백되면 자신도 롤백
NEVER
: 강제로 트랜잭션 사용 불가 지정
트랜잭션이 존재하면 예외 발생

@Transactional은 AOP의 한 종류인데,

자기 자신의 메서드를 호출하면 proxy를 거치지 않아서 AOP가 적용되지 않는다.
따라서, @Transactional이 적용이 안되는 것이다.
클래스를 분리해준다!!
proxy 객체를 통해 해당 메서드를 호출해주면 @Transactional이 잘 적용된다.
트랜잭션 사용할 때 주의해야할 사항은???
Self-invocation 문제가 발생할때 주의해야합니다.
대상 객체(Target) 내에서 자신의 메서드를 호출할 때 AOP가 적용이 안됩니다.
AOP는 프록시 객체 내에서 적용이 되는 것이다.
예외는 항상 상위로 전파된다.


따라서, 자식 트랜잭션에서 예외가 발생하면 부모트랜잭션에도 전파가되므로, 부모에서도 예외를 처리해주어야한다.
부모에서 try-catch로 처리해주어야한다.