월 15,400원
5개월 할부 시다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결스프링 DB 1편 - 데이터 접근 핵심 원리
UNCHECKED EXCEPTION 질문
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]uncheckedapptest 클래스에서 service class 부분입니다. service.logic()을 실행하면 먼저 repository.call()에서 runtimesqlexception이 발생하게 됩니다. 그럼 이 경우에 아래줄읜 networkclient.call()을 실행 안하고 바로 throw runtimesqlexception을 하게 되나요?이 부분에서 runtimesqlexception.class를 runtimeconnectexception으로 바꿔서 검증하면 에러가 납니다.!결론)1)이 코드가 작동할때는 runtimesqlexception이 발생해서 networkclient.calll()을 실행안하고 throw로 runtimesqlexception만 던지는지2) 그럼 서블릿은 runtimeconnectexception이 발생했다는 것을 인지를 전혀 못하는지 3)마지막 사진에서 runtimesqlexception.class대신 runtimeconnectexception.class로 바꿔 실행하면 왜 초록불이 안들어오는지 궁급합니다!궁금합니다!!
- 미해결스프링 DB 1편 - 데이터 접근 핵심 원리
DriverManager 가 Driver 후보들을 가지는 방법
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)예[질문 내용]안녕하세요. 데이터베이스 연결을 보면서 궁금증이 생겼습니다.DriverManager 는 제공받은 url 을 핸들링할 수 있는 Driver 구현체를 찾는다고 이해했는데요.DriverManager 는 위의 검증 이전에 어떻게 Driver 구현체들을 후보로 리스트로 들고있게되나요?
- 해결됨스프링 DB 1편 - 데이터 접근 핵심 원리
체크 예외 -> 언체크 예외 전환 시 질문
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]안녕하세요 체크 예외를 런타임 예외로 변환하는 과정에서 강의의 예시에서는 ConnectException을 RuntimeConnectException으로, SQLException은 RuntimeSQLException으로 변경해서 throws가 전파되는 것을 막는 모습을 볼 수 있었는데요.이런 상황에 있을 때, SQLException이나, ConnectException같은 경우는 예외가 발생했을 때 애플리케이션 단에서 처리를 못하니, 예외 문서에 작성해두고, 예외를 잡지 말고 발생하게두나요? Controller 사용중이라면 ControllerAdvice를 통해서 해결을 하면 될텐데, Rest API를 사용중이라면 RestControllerAdvice에서 ExceptionHandler를 통해 예외를 잡지 않고 강의에서 말씀하신 것처럼 500으로 던지는 지가 궁금합니다.강의의 초점이 막을 수 없는 체크 예외가 발생했을 때 이를 throws를 통해 전파하기보다 런타임 예외로 바꿔서 예외 문서를 잘 처리해서 깔끔한 코드를 만들자로 이해하면 되는 걸까요?
- 해결됨스프링 DB 1편 - 데이터 접근 핵심 원리
Translator 종류
안녕하세요 스프링의 편한 예외 전환 강의 감사합니다. 궁금한 점이 있습니다.repository에서 sql문법에러든 DuplicateKey 에러든 자동적으로 넘어온다고 했잖아요?그런데 그럴려면 각각 대충 예상하고 Repository 에서 Translator 종류를 다르게 정의해야 하죠?예를 들어 강의에서는선언 private final SQLExceptionTranslator exTranslator; (중략) //생성자에서 this.exTranslator = new SQLErrorCodeSQLExceptionTranslator(dataSource); (중략) // catch 부분에서 throw exTranslator.translate("save", sql, e);라고 했는데요위와 같은 상황에서는 DuplicateKeyException은 터질 수 없는 것 맞죠?SQLExceptionTranslator 인터페이스를 구현하고 있는 클래스에는 DuplicateKeyException 클래스가 없더라구요 (DuplicateKeyException는 올라가보니 NonTransientDataAccessException 클래스를 상속 받을받음) 그렇다면 변형된 스프링 에러가 넘어오게 하려면(translator) 각각 다른 Translator 인터페이스와 그에 맞는 구현클래스를 사용해야 하는 것 맞을까요?
- 해결됨스프링 DB 1편 - 데이터 접근 핵심 원리
오타
좋은 강의 감사합니다. pdf 6. 스프링과 문제 해결 - 예외 처리, 반복11페이지에 MemberServiceV4Test 클래스에 @Slf4j 가 필요합니다. 중요친 않지만..좋은 강의 제공해주셔서 감사해서 말씀드립니다.
- 미해결스프링 DB 1편 - 데이터 접근 핵심 원리
전환 예외시 네이밍 관례
안녕하세요 늘 좋은 강의 감사합니다! 이번 예외편 너무나 잘 들었습니다. 예전부터 너무 궁금했는데 어떤 식으로 해결하는지 한번에 정리가 되네요. 궁금한 점이 있는데요.체크드 예외 -> 런타임 예외로 변경해서 처리하잖아요.1. 네이밍관례는 어떤 식으로 될까요? 물론 회사마다 다르겠지만, SQLExcpetion -> RuntimeSQLExcepton 처럼 "Runtime" + "체크트예외네이밍" 을 붙이는 식으로 변환하는 걸까요? 영한님이 평소에 말씀하시는 "일반적으로" 가 궁금합니다. 메이저IT 기업의 예처럼요. 2.SQLException을 이어받을 예외를 RunTimeSQLException 클래스로 만들었다고 한다면, 그 안에는 보통 (Throwable cause)를 받는 생성자 하나 정도만 만들어 놓고 다른 추가 작업은 필요한 것이 없을까요? 이것도 위처럼 보통 어떤 식으로 처리하는지 궁금합니다. 감사합니다.
- 해결됨스프링 DB 1편 - 데이터 접근 핵심 원리
static class 의 new 생성자
강의에서 중요한 부분은 아닙니다만, CheckedTest 클래스와 UnCheckedTest 클래스 내부 클래스에서 각각 Service, Repository 클래스를 내부 static 으로 선언을 했잖아요? 그런데 static으로 선언되었음에도 두 클래스는, new Service(), new Repository() 로 생성이 되는 것이 이해가 안됩니다. 감사합니다.
- 해결됨스프링 DB 1편 - 데이터 접근 핵심 원리
설정파일 못 찾는 에러
안녕하세요 좋은 강의 감사합니다. ('스프링 부트의 자동 리소스 등록' 강의)강의의 뒷부분에서 application.properties에설정을 다 한 후에 테스트를 돌리면와 같은 에러가 뜹니다.코드는 아래와 같이 재확인했구요.그래서 설정파일을 설정을 변경해봤습니다.우측 상단의 edit configurations.. 에서 원래대로 비워두고 설정한 후에,메인컨테이너는 아래 같이 잘 뜨는데 테스트는 실패합니다.아래 (local) 설정을 하고 설정파일도(application-dev.properties)로 하고 dataSource내용 다 기입후 설정을 아래같이 해도 안됩니다.설정파일을 못 찾아서 dataSource 를 주입 못 받는 것 같습니다.application.properties에 first.name=hi 라고 한 후테스트에서@Value(value = "${first.name}")private String name; 후에 name을 찍어봐도 null로 게속 나옵니다.
- 미해결스프링 DB 1편 - 데이터 접근 핵심 원리
lock 이 걸리는 시점에 대한 의문
강의를 듣던중 궁금한 점이 생겨 질문드립니다.아래의 코드는 MemberServiceV2의 두 함수 입니다.public void accountTransfer(String fromId, String toId, int money) throws SQLException { Connection con = dataSource.getConnection(); try { con.setAutoCommit(false); // ! 트랜잭션 시작 // * 비즈니스 로직 bizLogic(fromId, toId, money, con); con.commit(); // * 성공시 commit } catch (Exception e) { con.rollback(); // ! 실패시 rollback throw new IllegalStateException(e); } finally { release(con); } } private void bizLogic(String fromId, String toId, int money, Connection con) throws SQLException { Member fromMember = memberRepository.findById(toId, con); Member toMember = memberRepository.findById(toId, con); ---<다른 db 커넥션에 의해 침범될 수 있는 구간>--- memberRepository.update(fromId, fromMember.getMoney() - money, con); validation(toMember); memberRepository.update(toId, toMember.getMoney() + money, con); }트랜잭션을 사용하기 위해서 con.setAutoCommit(false) 를 사용하고 있는데,강의를 듣고 이해한 내용에 의하면, accountTransfer에 의해서 db에 요청되는 sql 쿼리는 총 4개입니다.memberRepository.findById -> select 문 (2번)memberRepository.update -> update 문 (2번)그런데, select for update가 아닌 select문은 선택된 row에 대해 lock을 걸지 않기 때문에, 위의 코드에 적어놓은 것 처럼 update문이 수행되기 전에 다른 db 세션에 의해서 동일한 데이터가 수정될 여지가 있는 것 같아 보입니다.(update 문이 수행될 때 lock이 걸리는게 맞다면)그럼, findById 함수 내의 sql문을 select for update로 변경하거나, 코드에 적어놓은 select문과 update 문 사이에 또다른 lock을 설정해주어야하는 건가요? + 만약, 또다른 lock을 설정해야한다면 어떻게 해야하나요? P.Shttps://www.inflearn.com/questions/653523아래의 유사한 질문을 발견했는데, 해당 질문의 답변만으로 충분히 이해가 되지 않아서 추가적으로 질문드린 것입니다.
- 해결됨스프링 DB 1편 - 데이터 접근 핵심 원리
@Autowired
안녕하세요 항상 좋은 강의 감사드립니다. 영한님. MemberServiceV3_3Test 에서 필드 주입을 하잖아요?@Autowire 으로 MemberRepositoryV3, MembrerServiceV3_3 를 주입받는데요. 그런데 정작 MemberRepositoryV3 클래스와MembrerServiceV3_3는 Bean으로 등록되어 있지 않은데(@Component로 등록X) 어떻게 주입을 받아서 사용하는 것인가요? DI 중에서 필드주입(@Autowired)는 생성자 주입과 달리 미리 Bean으로 등록해서 주입을 해주기 때문인가요? (그런데 그렇다 하더라도 일단 @Component로 등록 자체가 안되어 있는데 의문이 듭니다) 미리 감사드립니다.
- 해결됨스프링 DB 1편 - 데이터 접근 핵심 원리
select ~ for update 락
안녕하세요 좋은 강의 항상 감사합니다.해당 강의에서 조회 락을 위해서 세션1에서 select ~ for update 을 사용하잖아요? 해당 쿼리를 사용해서 lock을 얻은 상태인데요.그런데 조회 중에 세션1(세션2 말고) 에서 바로 update 문을 날리게 된다면 바로 수정이 이루어지는데, 위 쿼리를 통해서 lock을 얻은 것은 update문을 날리게 되면 자동으로 반납이 됨과 동시에 update 문이 실행이 되는 것인가요? 감사합니다.
- 해결됨스프링 DB 1편 - 데이터 접근 핵심 원리
SET LOCK_TIMEOUT 10000;
안녕하세요 좋은 강의 항상 감사합니다. 해당 강의에서 2번째 세션에서만 SET LOCK_TIMEOUT 10000; 을 실행하는데, 락 타임아웃은 세션마다 다르게 설정을 할 수가 있는 것인가요?실습에서 SET LOCK_TIMEOUT 10000; 명령어만 세션1로 옮겨서 (순서, query 다 그대로 세션1, 세션2 각각 다 수행) 실행하니 같은 에러가 발생하는데요. 그렇다면 세션마다 설정하는 것이 아니라 더 큰 개념인 DB에 설정하는 것이라고 볼 수 있는, h2 시간이 정확하지 않아 단정짓기가 좀 어렵네요. 답변 미리 감사드립니다.
- 해결됨스프링 DB 1편 - 데이터 접근 핵심 원리
리소스 반환순서
Connection이 PreparedStatement의 전제조건이므로, Connection을 반환하면 PreparedStatement 은 자동반환되지 않는 것인가요? 감사합니다.
- 미해결스프링 DB 1편 - 데이터 접근 핵심 원리
throw 예외
안녕하세요 좋은 강의 항상 감사합니다.6:35에 31라인에서굳이 catch 로 잡은 SQLException을 왜 굳이 밖으로 throw e 하는 이유가 있을까요? 감사합니다.
- 해결됨스프링 DB 1편 - 데이터 접근 핵심 원리
static 함수
안녕하세요 좋은 강의 항상 감사합니다. 강의에서 DBConnectionUtil 클래스에서 Connection 을 반환하는 getConnection() 함수를 static 으로 만든 이유가 있을까요? 친절한 답변 미리 감사드립니다.
- 미해결스프링 DB 1편 - 데이터 접근 핵심 원리
트랜잭션범위
안녕하세요. 메소드마다 트랜잭션프록시가 생성되는건가요? 아님 트랜잭션범위를 지정해줄수있는건가요? 어노테이션은 말고는 aop의 포인트컷등으로 사용해서 메소드에서 트랜잭션이 생성하고 종료될것인지를 정할수잇는건가요?
- 해결됨스프링 DB 1편 - 데이터 접근 핵심 원리
테스트 코드에서의 생성자 의존관계 주입 관련하여 질문 드립니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요.안녕하세요. 강의 복습 중 해결되지 않는 의문점이 있어서 질문 드립니다. 테스트 코드에서 @TestCOnfiguration을 통해 해당 테스트 클래스에서 사용할 빈들을 등록을 하고, 의존성 주입을 할 때필드 주입은 정상 동작하지만, 생성자 주입은 정상 작동하지 않는지 의문이 생겨 질문 드립니다. 영한님께서는 필드 주입을 하셨고, 저는 복습 중에 생성자 주입으로 한 번 해볼까 하여 시도를 해봤는데 정상 동작하지 않았습니다. 아래는 생성자 주입을 시도해본 코드입니다./** * JDBC - 트랜잭션매니저를 통한 트랜잭션 + 트랜잭션 AOP(@Transactional) */ @SpringBootTest @RequiredArgsConstructor class MemberServiceV3_3Test { private static final String MEMBER_A = "memberA"; private static final String MEMBER_B = "memberB"; private static final String MEMBER_EX = "ex"; private final MemberServiceV3_3 memberService; private final MemberRepositoryV3 memberRepository; @TestConfiguration static class TestConfig { @Bean DataSource dataSource() { HikariDataSource dataSource = new HikariDataSource(); dataSource.setJdbcUrl(URL); dataSource.setUsername(USERNAME); dataSource.setPassword(PASSWORD); return dataSource; } @Bean PlatformTransactionManager transactionManager() { return new DataSourceTransactionManager(dataSource()); } @Bean MemberRepositoryV3 memberRepositoryV3() { return new MemberRepositoryV3(dataSource()); } @Bean MemberServiceV3_3 memberServiceV3_3() { return new MemberServiceV3_3(memberRepositoryV3()); } } @AfterEach void after() throws SQLException { memberRepository.delete(MEMBER_A); memberRepository.delete(MEMBER_B); memberRepository.delete(MEMBER_EX); } @Test @DisplayName("정상 이체") void accountTransfer() throws SQLException { memberRepository.save(new Member(MEMBER_A, 10000)); memberRepository.save(new Member(MEMBER_B, 10000)); // 커밋 memberService.accountTransfer(MEMBER_A, MEMBER_B, 2000); Member fromMember = memberRepository.findById(MEMBER_A); Member toMember = memberRepository.findById(MEMBER_B); assertThat(fromMember.getMoney()).isEqualTo(8000); assertThat(toMember.getMoney()).isEqualTo(12000); } @Test @DisplayName("이제 중 예외 발생") void accountTransferEx() throws SQLException { memberRepository.save(new Member(MEMBER_A, 10000)); memberRepository.save(new Member(MEMBER_EX, 10000)); // 예외 발생 // 롤백 assertThatThrownBy(() -> memberService.accountTransfer(MEMBER_A, MEMBER_EX, 2000)) .isInstanceOf(IllegalStateException.class); Member fromMember = memberRepository.findById(MEMBER_A); Member toMember = memberRepository.findById(MEMBER_EX); // 정상 이체 X // 롤백을 통해 돈은 트랜잭션 시작 전으로 복구된다. assertThat(fromMember.getMoney()).isEqualTo(10000); assertThat(toMember.getMoney()).isEqualTo(10000); } } (추가 질문)혹시나 해서 final 키워드를 제거하고 시도해보니 생성자 주입도 정상 동작하는 것을 발견했습니다. 테스트 코드를 실행할 때 어떤 과정 때문에 이러한 현상이 발생하는 지 궁금합니다.. 아래는 final 키워드를 제거한 코드입니다./** * JDBC - 트랜잭션매니저를 통한 트랜잭션 + 트랜잭션 AOP(@Transactional) */ @SpringBootTest class MemberServiceV3_3Test { private static final String MEMBER_A = "memberA"; private static final String MEMBER_B = "memberB"; private static final String MEMBER_EX = "ex"; private MemberServiceV3_3 memberService; private MemberRepositoryV3 memberRepository; @Autowired public MemberServiceV3_3Test(MemberServiceV3_3 memberService, MemberRepositoryV3 memberRepository) { this.memberService = memberService; this.memberRepository = memberRepository; } @TestConfiguration static class TestConfig { @Bean DataSource dataSource() { HikariDataSource dataSource = new HikariDataSource(); dataSource.setJdbcUrl(URL); dataSource.setUsername(USERNAME); dataSource.setPassword(PASSWORD); return dataSource; } @Bean PlatformTransactionManager transactionManager() { return new DataSourceTransactionManager(dataSource()); } @Bean MemberRepositoryV3 memberRepositoryV3() { return new MemberRepositoryV3(dataSource()); } @Bean MemberServiceV3_3 memberServiceV3_3() { return new MemberServiceV3_3(memberRepositoryV3()); } } ..... }
- 해결됨스프링 DB 1편 - 데이터 접근 핵심 원리
강의 순서
안녕하세요현재 스프링 MVC 1편을 수강중입니다.강의만 듣다보니 제가 직접 뭔가 만들어보면서 내용들을 익히고, 개발 과정에 대해 좀 더 파악하고 싶어졌습니다. MVC 2편과 DB 2편을 제외한 MVC 1편, DB 1편까지만 듣고 간단한 프로젝트를 진행한 다음에 나머지 2편들을 수강하여도 문제가 없을까요?
- 미해결스프링 DB 1편 - 데이터 접근 핵심 원리
히카리데이터소스가 없어요
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요.뭔가 이상해서 mavenrepository에서 hikari cp 를 추가해도 안뜨고 왜안뜨는지 잘모르겠어 hikari cp 추가전에는 jdbc 하나 넣어서이상태입니다.
- 해결됨스프링 DB 1편 - 데이터 접근 핵심 원리
테스트 코드에서 Connection.close 메서드를 호출해주지 않아도 괜찮나요?
안녕하세요.이번 수업 시간에 테스트 코드를 통해 커넥션 예제를 보여주셨는데, 코드 상으로는 close 메서드를 호출해주지 않으셔서 질문 남깁니다.@Slf4j public class ConnectionTest { /** * DriverManager */ @Test void driverManager() throws SQLException { Connection con1 = DriverManager.getConnection(URL, USERNAME, PASSWORD); Connection con2 = DriverManager.getConnection(URL, USERNAME, PASSWORD); log.info("con1: class = {}, connection = {}", con1.getClass(), con1); log.info("con2: class = {}, connection = {}", con2.getClass(), con2); } /** * DataSourceDriverManager */ @Test void dataSourceDriverManager() throws SQLException { // DriverManagerDataSource - 항상 새로운 커넥션 획득 DriverManagerDataSource dataSource = new DriverManagerDataSource(URL, USERNAME, PASSWORD); Connection con1 = dataSource.getConnection(); Connection con2 = dataSource.getConnection(); log.info("con1: class = {}, connection = {}", con1.getClass(), con1); log.info("con2: class = {}, connection = {}", con2.getClass(), con2); } }close 메서드를 호출해주지 않아도 내부적으로 알아서 커넥션을 제거해주는 것 같은데, 혹시 이에 대한 보충 설명을 해주실 수 있을까요..?