묻고 답해요
129만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결스프링 DB 1편 - 데이터 접근 핵심 원리
DB Connection 관련하여 질문드립니다.
@Transactional 선언된 메서드를 사용할 때, Connection이 사용되고 반환되는 시점이 궁금합니다.@Transactional 메서드 호출 -> 쿼리 실행 -> 외부 API 호출 -> @Transactional 메서드 종료 라고 했을 때, @Transactional 시작 시점부터 끝날 때까지 하나의 커넥션이 유지되나요? 아니면 쿼리가 실행될 때, 그리고 커밋/롤백 될때만 커넥션을 사용(커넥션 opne & close)하나요?
-
해결됨스프링 DB 1편 - 데이터 접근 핵심 원리
클래스 @Transactional
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]강의에서 클레스에 @Transactional를 넣을 수 있다고 하였는데 그럼 그 클래스 내부에 있는 모든 메서드에 @Transactional가 붙는건가요? 아니면 특정 몇몇 메서드에만 붙는건가요? 만약 특정 몇몇 메서드에 붙는다고 한다면 그 조건이 무엇인가요?
-
미해결스프링 핵심 원리 - 기본편
@Transactional 안에서 외부 서비스 api call 관련 질문있습니다.
@tranactional 이 붙은 메소드 안에서 외부 서비스 api를 call 해야하는 상황이 있는데컨트롤러 단에서 로직 분리가 힘든 상황입니다. @tranactional 이 붙은 메소드 안에서 아래와 같이 TransactionSynchronizationManager를 선언하고 override한 aftercommit 내부에서 호출하게 될 경우마찬가지로 외부 서비스 api에 장애가 발생했을 때도 본 서비스에 장애로 이어질 수 있을까요?? TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() { @Override public void afterCommit() { // 여기서 외부서비스 api 호출 } });
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
@PostConstruct 지정 함수 @Transactional 지정 시 컨텍스트 관리가 안되는 경우
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예 역시 백문이 불여일타!! 강의 보고 혼자 샘플작성하다 막 터집니다. 강의 볼때는 '음~ 그렇지~' 하고 보던게 안보고 혼자 작성해보니 강사님이 말씀하시는 "이거 분명이 개발할 때 문제 발생합니다." 하는거 다 터지네요. [질문 내용] InitDB.java 샘플 따라하다가 궁금한점이 생겨 질문 드립니다. 애플리케이션 구동 시 초기 데이터를 넣기 위해 @PostConstruct 로 코드를 작성하는 부분에서 문제가 발생했습니다. "Caused by: javax.persistence.TransactionRequiredException: No EntityManager with actual transaction available for current thread - cannot reliably process 'persist' call" 결론은 영속성 관리가 안되는 문제인거 같습니다. 근데 @Transactional을 붙였고 내부 함수 호출도 아닌데 왜 관리가 안되냐해서 디버깅을 해봤습니다. PostConstruct 하는 부분을 따라가 보니 해당 함수를 invoke하는 클래스가 프록시가 아니더군요. InitDB의 내부 맴버는 프록시인데. 질문: PostConstruct를 호출되는 대상 클래스도 spring container에 있는 bean같은데 왜 저넘은 프록시가 아닌거죠? 다른 bean의 맴버로 주입되는 bean만 프록시인 건가요?
-
해결됨실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
Controller, Service, Repository 구조에서 Transaction 관련 질문
안녕하세요? 강의 내용 중 질문이 있어서 글 남깁니다. 아직 전체 강좌를 본 건 아니지만 말씀하신 Controller, Service, Repository 구조에서 Service 구조가 단순 Repository 에 위임하는 기능만 있는 경우, Controller 에서 직접 Repository 를 호출하는 것도 괜찮다고 하셨는데 이 경우에 Transactional 은 어느쪽에서 관리하는 게 좋을까요? Controller or Repository 둘 중 어느 곳에서 관리하는게 좋을지? 얼핏 생각하면 Controller 에서 관리하는 게 좋을 것도 같은데 간단한 구조라면 Repository 에서 관리해도 될 것 같아서요. 그리고, 혹시 Controller 에서 Transactional 을 처리하는 경우, 예전에 문제가 생길 수 있다고 들었던 것도 같아서 질문 납깁니다.
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
서비스 계층에 트랜잭션 추가 하는 이유
서비스 계층에 @Transactional 을 추가하셨는데 이유가 궁금하고 그 역할이 궁금합니다! Test클래스의 메서드 위에 붙인거랑은 어떤차이가 있는건가요??
-
미해결
테스트 코드 Transactional, flush
안녕하세요! jpa 수업듣고 혼자 공부하다가 궁금한 점이 생겨서 질문 남깁니다. @Repository@Transactional@RequiredArgsConstructorpublic class ItemRepositoryImpl implements itemRepository{ private final EntityManager em; @Override public void delete(Long itemId){// Item item=findOne(itemId);// em.remove(item); em.createQuery("delete from Item i where i.id = :id") .setParameter("id",itemId).executeUpdate(); } @RunWith(SpringRunner.class)@SpringBootTest@Transactionalpublic class ItemRepositoryTest { @Autowired ItemRepository itemRepository; @Autowired private EntityManager em; private User user; private Item item; @Test public void delete(){ Long itemId= itemRepository.save(item); System.out.println(itemId); itemRepository.delete(itemId);// 1) System.out.println(itemRepository.findOne(itemId).getId()); Assertions.assertEquals(null,itemRepository.findOne(itemId)); } 테스트코드를 이렇게 작성하는 경우에는 delete가 다시 rollback되고 테스트 코드에서 1) 부분에서 rollback이 되고 itemRepository.findOne(itemId)가 itemId로 나오던데 @Transactional가 잘못 적용된 것인가요? jpql을 사용하는 경우 flush가 일어나서 flush 과정에서 commit이 일어나고 테스트 코드에서는 이 commit때문에 rollback이 일어나는 것 같은데 제가 생각한 것이 맞나요? 만약 제가 생각한 것이 맞다면 테스트 코드 부분에 1)에서 롤백이 일어나서 테스크코드 delete 메소드에서 save(item)부분도 롤백이 되서 itemRepository.delete(itemId)를 한 이후에는 find해도 null이 나와야하는데 그대로 itemId가 나오는 이유가 뭘까요? 주석처리한 것처럼 em.remove를 사용하면 테스트에 성공하는데 그 이유는 뭘까요ㅜㅜ
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
통합 테스트 진행 도중 JdbcMemberRepository Transaction 관련 에러 문의
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용] 현재 상황 스프링 DB 접근 기술 > 스프링 통합 테스트 수업을 듣던 도중 MemberServiceIntegrationTest.java 파일에서 회원가입() Test를 진행하던 도중 'java.sql.SQLException: Connection is closed'이라는 에러가 발생하는 상황입니다. 질문 게시판에서 확인해보니 현재 미해결된 상황이라 이렇게 다시금 글을 남깁니다. 구글링하여 확인해보니 @Transactional과 Connection객체의 트랜잭션 중복 문제인것 같은데... 어떻게 수정해야 할지 감이 안잡혀서 질문남깁니다. 하단에 공유 링크 첨부합니다. 확인해주시면 감사하겠습니다. Google Drive Link https://drive.google.com/file/d/1KBANfw1MXw3anPnnlIQgHzs5kolswUsd/view?usp=sharing 궁금한 점 구글에 검색해보니 connection 객체의 AutoCommit을 false로 설정하거나, TransactionSynchronizationManager.initSynchronization() 함수를 사용하여 트랜잭션을 동기화하여 처리하는 방식으로 사용하면 될것이다 라는 의견들이 있었습니다. initSynchronization()함수를 사용하니 'Cannot activate transaction synchronization - already active'이런 식의 에러가 발생하고 AutoCommit을 false로 설정하니 변함없이 Connection is closed라고 표시되더군요. 어떠한 방식을 사용해서 진행해야 에러를 잡을 수 있을지 궁금합니다. 로그를 찍어보니 JdbcMemberRepository.java의 pstmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS); 이부분에서 에러가 발생하는 것 같은데... try catch로 감싸게 된다면 어떠한 Exception으로 감싸면 되는지도 궁금합니다.(IllegalStateException으로 감싸면 될까요...?)
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
추상클래스와 @transactional 질문입니다.
안녕하세요 영한님 JPA 수업을 정말 잘듣고 있으며 이 수업을 듣고 제가 실무에서 적용을 하면서 인정받고 있어서 정말 감사합니다.실무를 하던 중 문제는 해결하였으나 원리가 잘 이해가 안가는 부분이 있는데 구글리을 해도 좀처럼 나오지 않아 이렇게 질문을 드립니다 문제가 되는 코드는 실무코드라 간추린 버전으로 올리겠습니다. 추상클래스 입니다. method1()은 구현을 했으며 method2()는 추상메소드입니다 구현클래스이고 추상 메소드인 method2만 오버라이딩하여 구현했습니다 이상황에서 ExampleClass ex = new ExampleClass(); ex.method1(); 이렇게 실행했을 때 저는 생각한 것이 - ExampleClass는 상속을 받았으므로 method1()이 있다. - ExampleClass에 @transactional을 걸었으므로 method1()에도 @transactional이 걸릴 것이다 그런데 막상 실행해보니 트랜잭션이 실행되지 않더군요 그래서 여러가지시도를 한 결과 부모클래스인 AbstractExampleClass에 @transactional을 걸으니 해결되었었습니다. 그런데 문제는 해결했으나 원리가 잘 이해가 되지 않습니다. - ex.method1()를 실행하면 ExampleClass에 @transactional이 있으므로 AOP에서 트랜잭션을 실행해주는 것이 아닌가? 이런 생각이 들더군요 아마 제가 @transactional과 AOP의 자세한 구동원리를 잘 몰라서 그런거 같은데 왜 ExampleClass에 @transactional을 붙이면 안되고 추상클래스에 붙여야 하는지 원리를 자세히 알 수 있을까요?
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
Transactional에 관해서..
8분20초경에 @Transactional이 테스트 끝나면 롤백시켜주는 애노테이션이라고 하신거같은데 트랜잭션쓰기전에 테스트를 2번실행해서 오류가 난거는 오토커밋이 자동으로 설정이 되어있어서 그런건가요? 만약 설정이 되어있다면 그게 어디에서 설정이 된건가요?
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
세션 2개 상황에서 동시성 문제
스승님 그간 평안하셨는지요,, 다름이 아니라 불초의 제자 질문이 있어 이 야심한 시간에 편지 올립니다. WAS를 한대만 운용한다는 가정하에 사용자의 접속 세션 허용범위를 2개로 주었어요, 웹으로 접속함과 동시에 모바일에서도 접속이 가능하게 만들어 주었다고 생각해 보았습니다. 전에 아래와 같은 말씀을 해주셨는데 ---------------------------- 서버가 한대만 있고, 자바(JVM)로 웹 애플리케이션을 단 하나만 구동하는 상황이면 자바 만으로 동시성 제어를 할 수 있습니다. 그런데 실무에서는 보통 서버 두 대 이상을 사용하기 때문에, 동시성 제어를 JVM안에서 해결하는게 어렵습니다. 관계형 데이터베이스는 이런 동시성 제어를 고려해서 개발되었기 때문에, 결국 관계형 데이터베이스에 동시성 제어를 위임해야 합니다. 그 중에 관계형 데이터베이스가 제공하는 유니크 제약조건을 사용하면, 같은 이름을 절대로 동시에 저장할 수 없습니다. 그래서 name에 유니크 제약조건을 실무에서는 걸어주어야 한다고 이야기 했습니다. 그런데 이런 유니크 제약조건은 정말 최악의 경우(진짜 초 단위로 같은 데이터가 저장되었을 때)가 발생했을 때 동작하는 것이고, 대부분은 validation에서 막힙니다. ----------------------------- 위에서 제가 가정한 상황에서 사용자가 웹이랑 모바일에서 동시에 요청을 보냈는데 그게 하필 동시성 문제를 일으킨다면 이런 상황에서도 데이터베이스 lock을 안걸고 자바만으로 동시성을 제어할 수 있는 방법이 있을까요?? (혹은 세션이 2개가 아니더라도 1개의 세션에 1 명의 사용자가 동시에 같은 요청을 보낼 경우에두요!,, 너무 여러개 번거로운 질문 죄송합니다 ,, ㅠㅠ)
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
안녕하세요 영한님 @Transactional 및 open에 관하여 질문이 있습니다.
안녕하세요 영한님! 강의 내용을 코틀린 기반으로 작성해보고 있는데요! 조금 다른 부분들이 있긴 하지만 여러 리서치를 해보며 정상 동작하는 것들을 확인했는데 굉장히 특이한 문제를 만나서 조언을 구하고자 질문 드립니다. MemberService의 MemberRepository를 SpringConfig에서 의존성 주입을 해준 뒤 실제 메서드에서 해당 repository를 호출해보니 repository가 null이어서 접근할 수 없다는 메시지와 함께 에러가 발생하였습니다. 이에 대해 조금 조사해 본 결과 @Transactional를 추가하게 되면 구성된 의존성에 접근이 되지 않는 문제가 있었습니다. 그러나 이 생성자에서 받아온 의존성을 open 제한자로 변경하여 받아오면 접근이 되는 기묘한 현상이 발생하더군요! 관련해서 해결책을 찾은 경로는 여기였습니다. https://stackoverflow.com/questions/41298289/spring-boot-autowired-with-kotlin-in-service-is-always-null 혹시 강의 내용과는 조금 차이가 있지만 왜 이런 현상이 발생하는지 알 수 있을까요? 강의 너무 잘 듣고 있습니다. 항상 감사합니다!