스프링/6. 스프링 DB-2 59

50. 트랜잭션 전파 3

본격적으로 트랜잭션 전파에 대해 알아볼 것이다. 트랜잭션이 중첩적인, 그러니까 트랜잭션 도중 트랜잭션이 끝나지 않았는데(commit or rollback) 또 트랜잭션을 마주 한다면? 기존의 트랜잭션을 이어 받을 지, 새 트랜잭션을 만들어 진행 해야 할 지, 이런 것을 정하는 것이 트랜잭션 전파. propagation 우선, 트랜잭션 진행 중에 또 다른 트랜잭션을 시작하는 경우. 보통 트랜잭션을 이어 받는다..? 어.. 그렇기 보단 보통은 일단 스프링은 하나의 트랜잭션을 논리 트랜잭션이라고 정의한다. 그러니까, @Transactional 붙인거나 getTransaction 해서 시작하거나 해서 트랜잭션 도중의 범위들을 하나의 논리 트랜잭션 이라고 한다. 그리고, 이미 트랜잭션 진행 도중에 또 다른 트랜잭..

49. 스프링 트랜잭션 전파 2

이번엔 여러가지 상황을 살펴볼 건데, 트랜잭션 후, 다시 트랜잭션 @Test void doubleCommit(){ log.info("트랜잭션1 시작"); TransactionStatus status1 = txManager.getTransaction(new DefaultTransactionAttribute()); log.info("트랜잭션1 커밋 시작"); txManager.commit(status1); log.info("트랜잭션1 커밋 끝"); log.info("트랜잭션1 끝."); log.info("트랜잭션2 시작"); TransactionStatus status2 = txManager.getTransaction(new DefaultTransactionAttribute()); log.info("트랜잭션..

48. 스프링 트랜잭션 전파

트랜잭션이 둘 이상 있을 때 라던지, 아니면 저번에 트랜잭션 프록시에서 트랜잭션 아닌 거에서 트랜잭션을 호출했을 때 어떻게 동작하는 지 알아 봄. @Slf4j @SpringBootTest public class BasicTxTest { @Autowired PlatformTransactionManager txManager; @Test void commit(){ log.info("트랜잭션 시작"); TransactionStatus status = txManager.getTransaction(new DefaultTransactionAttribute()); log.info("트랜잭션 커밋 시작"); txManager.commit(status); log.info("트랜잭션 커밋 완료"); } @Test void ..

47. 트랜잭션과 예외 -활용

체크예외를 커밋하는 이유는 스프링 설계 자체가 비즈니스 예외는 체크예외, 언체크예외는 복구 불가능 한 예외라고 가정하고 설계 됨. 물론 꼭 따를 필요는 없음. 그냥 rollbackFor 이런 거 써도 되고. 비즈니스 예외라는 것은, 예를 들어 잔고부족 같은 거. 보통 이런 건 우리가 따로 비즈니스 적으로 예를 들어 잔고가 부족합니다! 이런 메시지를 클라이언트에게 전해주게 하던지 처리 해야 하니까. 주문데이터를 일단 저장하고, 결제 상태를 대기로 만들고, 고객에게 잔고 부족을 알리는 등. 이렇게 시스템 자체는 문제가 없지만 비즈니스 상황에 대해 있는 문제를 비즈니스 예외. 이런 비즈니스 예외는 굉장히 중요하고 반드시 처리해야 하는 경우가 많아서 체크 예외를 고려. 그래서 보통 예외 구분은 시스템 장애 예외..

46. 트랜잭션과 예외

Default는 런타임예외 발생 시 롤백, 체크예외 발생 시 커밋임. @SpringBootTest public class RollbackTest { @Autowired RollbackService service; @Test void runtimeException(){ assertThatThrownBy(()->service.runtimeException()) .isInstanceOf(RuntimeException.class); } @Test void checkedException(){ assertThatThrownBy(()->service.checkedException()) .isInstanceOf(MyException.class); } @Test void rollbackFor(){ assertThatTh..

44. 트랜잭션 AOP 주의사항 -초기화 시점

스프링 초기화 시점, 에는 트랜잭션 AOP가 적용이 되지 않을 수도 있다. Custom init() 저 부분 인 듯? 그러니까, @PostConstruct가 의존성 주입 이후 우리가 뭔가 초기화? 작업같은 거 해 두고 싶을 때 저거 붙인 메소드 만들면 알아서 실행이 되는데, 만약 @PostConstruct @Transactional 이렇게 있으면 @Transactional이 적용이 되지 않을 수도 있다. 순서가 @PostConstruct 등 초기화가 모두 된 다음에 프록시로써 쓸 수 있다. @SpringBootTest public class InitTxTest { @Autowired Hello hello; @Test public void initTx(){ } @TestConfiguration static..

43. 트랜잭션 AOP 주의사항 2 -프록시 내부호출

스프링 트랜잭션 AOP기능은 public 메소드만 적용 됨. 그리고 이건 실무에서도 쓰는 방법중 하나인데, @Transactional 없는 메소드 -> @Transactional 있는 메소드 이런 식 일시, @Slf4j @SpringBootTest public class InternalCallV2Test { @Autowired CallService callService; @Test void printProxy(){ log.info("callService class={}", callService.getClass()); } @Test void externalCallV2(){ callService.external(); } @TestConfiguration static class InternalCallV1Tes..

42. 트랜잭션 AOP 주의사항 -프록시 내부 호출

트랜잭션이 제대로 적용 안되는 문제, 그로 인하여 default인 오토커밋모드로 커밋되어 rollback을 해도 의도되로 안되는.. 우선 다음 코드를 보자. @Slf4j @SpringBootTest public class InternalCallV1Test { @Autowired CallService callService; @Test void printProxy(){ log.info("callService class={}", callService.getClass()); } @Test void internalCall(){ callService.internal(); } @Test void externalCall(){ callService.external(); } @TestConfiguration static ..

41. 스프링 트랜잭션 우선순위

이게 보니까 우리가 스프링 트랜잭션 한번 배웠긴 했는데 다시 배우는 게 이번에는 좀 더 깊게? 어떻게 일어나는 지 그거 보는거랑 트랜잭션 추가 기능? 트랜잭션에 우리가 @Transactional(옵션이름=값) 이런 식으로 줄 수 있는데, 우선순위라는 게 예를 들어 @Transactional(옵션1 = 값1) class TxClass{ @Transactional(옵션1 = 값2) public void txTest(){ } } 하면 저 값2가 적용된다는 이야기. 사실 더 자세할 수록 그것이 적용된다는 것은 어느정도 프로그래머 입장에서는 통설로 받아들여져서.. @SpringBootTest @Slf4j public class TxLevelTest { @Autowired LevelService service; @..

40. 스프링 트랜잭션 테스트

트랜잭션 가져왔다. 먼저, 테스트 환경에서 로그 보기 위해 testAnnotationProcessor 'org.projectlombok:lombok' testImplementation 'org.projectlombok:lombok' build.gradle에 추가, 그 다음 application.properties에 logging.level.org.springframework.transaction.interceptor = TRACE 로그 중 트랜잭션의 것을 인터셉트 해 오는데 TRACE 레벨을 인터셉트 해 옴 @Slf4j @SpringBootTest public class TxBasicTest { @Autowired BasicService basicService; @Test void proxyCheck()..