묻고 답해요
156만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결스프링 DB 1편 - 데이터 접근 핵심 원리
트랜잭션 매니저 관련해서 궁금한사항이있습니다.
[질문 템플릿]1. 강의 내용과 관련된 질문인가요?예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]만약에 트랜잭션 매니저를 본인이 직접만든다고했을때엔 빈 스코프 단위를 웹스코프 단위로 보통 설정하나요?
-
미해결토비의 스프링 부트 - 이해와 원리
ApplicationRunner 가 동작하지 않는 이유
테스트 환경에서는 application.properties를 읽지 않고 ApplicationRunner가 동작하지 않는다고 하셨습니다. 그래서 @TestPropertySource로 설정 파일을 넣어줬는데요 이게 동작하지 않는 이유는 테스트 환경은 스프링을 확장해서 스프링 컨테이너를 띄우고 구성 정보 클래스를 집어넣어서 빈 오브젝트만 등록하기 때문이 맞을까요 ? SpringApplication.run은 테스트 환경과 다르게 스프링 컨테이너를 띄우고 템플릿 매서드로 컨테이너를 띄우고 구성 정보 클래스를 활용해서 빈 오브젝트를 등록하는 거 외에 추가적인 Ruuner 나 Property 파일을 읽는 작업을 별도로 하기 때문인거죠 ?
-
해결됨스프링 DB 1편 - 데이터 접근 핵심 원리
예외 추상화 적용시 예외를 service단에서 처리하지 않을경우
안녕하세요 강의 내용 중 문제에 대한 제 생각을 확인차 질문드립니다. JDBC 기술에 종속적인 예외를 spring기술에 종속적인 예외로 바꿔주어 우리가 모든 데이터접근 기술의 예외코드를 알필요없이 문제를 처리할 수 있음을 알겠습니다. 이때 spring 이 제공하는 모든 예외는 RuntimeException이기 때문에 따로 service단에서 try catch로 잡지 않을 경우 생략된 throw로 controller -> servlet container로 자동으로 던져지는게 맞을까요?
-
해결됨토비의 스프링 부트 - 이해와 원리
자동 구성 정보 클래스를 작성한다면
@Configuration(proxyBeanMethods = false) static class MyConfig { private final Common common; public MyConfig(Common common) { this.common = common; } @Bean public Bean1 bean1() { System.out.println("bean1 생성자"); return new Bean1(common); } @Bean public Bean2 bean2() { System.out.println("bean2 생성자"); return new Bean2(common); } } @Configuration(proxyBeanMethods = false) static class MyCommonConfig { @Bean public Common common() { return new Common(); } }과@Configuration(proxyBeanMethods = false) static class MyConfig { @Autowired private Common common; public MyConfig() { } @Bean public Bean1 bean1() { System.out.println("bean1 생성자"); return new Bean1(common); } @Bean public Bean2 bean2() { System.out.println("bean2 생성자"); return new Bean2(common); } @Bean public Common common() { return new Common(); } }빈 구성 정보를 프록시 객체로 생성하지 않는다는 대안을 코드로 작성해보면 별도의 구성 정보를 사용하는 방식과내부에서 필드 주입으로 초기화 하는 방식이 생각났습니다. 별도의 구성정보를 사용하면 어떤 클래스를 의존하는지 생성자를 보고 확인할 수 있다는 장점과 테스트 코드를 작성할때 더 편할거라 생각이 들고,밑에 방식은 Common이라는 클래스가 MyConfig 에서만 사용된다면 관리하기도 편할거라 생각이 들었습니다. 그리고 설정 정보 클래스니까 굳이 생성자로 초기화를 하지 않아도 되지 않을까 라는 생각도 들었습니다. 강사님께서 Config 클래스도 테스트를 해봐야한다고 말씀해주셨는데 이런 경우라면 상황에 따라 선택해야하는 부분인가요 ?아니면 설정 정보도 환경에 따라 다를 경우가 있느니까 별도로 분리하는게 나을까요?
-
해결됨토비의 스프링 부트 - 이해와 원리
@Transactional 어노테이션을 붙이지 않은 테스트가 통과하는 이유
1. 문제HelloRepositoryTest 테스트 실행 시 findHelloFailed() 테스트 실패 및 에러 발생Expected :null Actual :tobyspring.hello.Hello@579846cc 2. 강의 정보제목: [섹션 10] 스프링 부트의 자동 구성과 테스트로 전환시간: 6:23내용: HelloRepositoryTest.java의 @HellobootTest를 @SpringBootTest로 변경 후 실행 3. 내 프로젝트 상태HelloRepositoryTest.java 코드package tobyspring.hello; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import static org.assertj.core.api.Assertions.assertThat; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE) public class HelloRepositoryTest { @Autowired private HelloRepository helloRepository; @Test void findHelloFailed() { assertThat(helloRepository.findHello("Toby")).isNull(); } @Test void increaseCount() { assertThat(helloRepository.countOf("Toby")).isEqualTo(0); helloRepository.increaseCount("Toby"); assertThat(helloRepository.countOf("Toby")).isEqualTo(1); helloRepository.increaseCount("Toby"); assertThat(helloRepository.countOf("Toby")).isEqualTo(2); } } 4. 해결 과정increaseCount() 테스트 실행 결과가 findHelloFailed() 테스트에 영향을 미치는 것으로 추정따라서 @Transaction을 @SpringBootTest 아래 줄에 추가package tobyspring.hello; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.transaction.annotation.Transactional; import static org.assertj.core.api.Assertions.assertThat; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE) @Transactional public class HelloRepositoryTest { @Autowired private HelloRepository helloRepository; @Test void findHelloFailed() { assertThat(helloRepository.findHello("Toby")).isNull(); } @Test void increaseCount() { assertThat(helloRepository.countOf("Toby")).isEqualTo(0); helloRepository.increaseCount("Toby"); assertThat(helloRepository.countOf("Toby")).isEqualTo(1); helloRepository.increaseCount("Toby"); assertThat(helloRepository.countOf("Toby")).isEqualTo(2); } } 5. 결과정상적으로 테스트 통과 6. 질문강의에서 @Transactional 어노테이션 없이 테스트를 통과할 수 있었던 이유가 궁금합니다!
-
해결됨토비의 스프링 부트 - 이해와 원리
DataSourceTest 테스트 실행 시 transaction 로그가 출력되지 않는 문제
1. 문제DataSourceTest 테스트 실행 시 transaction 로그가 출력되지 않음INFO o.s.t.c.transaction.TransactionContext : Began transaction (1) for...(생략) INFO o.s.t.c.transaction.TransactionContext : Rolled back transaction for...(생략) 2. 강의 정보제목: [섹션 10] 스프링 부트의 자동 구성과 테스트로 전환시간: 6:00내용: DataSourceTest.java의 @HellobootTest를 @JdbcTest로 변경 후 로그 보기 3. 내 프로젝트 상태자바 버전: 17스프링 부트 버전: 3.2.0build.gradle의 의존성repositories { mavenCentral() maven { url 'https://repo.clojars.org' name 'Clojars' } } dependencies { implementation ('org.springframework.boot:spring-boot-starter-web') implementation 'org.springframework:spring-jdbc' runtimeOnly('com.h2database:h2:2.2.220') implementation 'hikari-cp:hikari-cp:3.0.1' testImplementation 'org.springframework.boot:spring-boot-starter-test' }DataSourceTest.java 코드@JdbcTest public class DataSourceTest { @Autowired DataSource dataSource; @Test void connect() throws SQLException { Connection connection = dataSource.getConnection(); connection.close(); } } 4. 해결 과정application.properties에 로그 단계를 정의logging.level.ROOT=DEBUG logging.level.org.springframework.transaction=DEBUG 5. 결과단계를 DEBUG -> TRACE로 다양하게 바꾸고 테스트를 실행했으나 transaction은 출력되지 않음 6. 질문강의 중간에 로깅 단계를 바꾸는 작업이 있었는데 제가 그 부분을 놓친 것인지스프링 부트의 버전이 올라가며 transaction 로그를 출력하지 않도록 바뀐 것인지아니면 다른 방식으로 접근해야 하는 것인지궁금합니다!
-
해결됨스프링 DB 1편 - 데이터 접근 핵심 원리
JDBC 이해 강의에서 DB연결 에러
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요. 김영한 선생님 안녕하세요. JDBC 이해에서 데이터베이스를 연결하려고 하는데 계속 에러가 납니다. 에러내용 java.lang.IllegalStateException: org.h2.jdbc.JdbcSQLNonTransientConnectionException: Database may be already in use: "C:/Users/SeoCom1/testDB.mv.db". Possible solutions: close all other connection(s); use the server mode [90020-224] at hello.jdbc.connection.DBConnectionUtil.getConnection(DBConnectionUtil.java:17) at hello.jdbc.connection.DBConnectionUtilTest.connection(DBConnectionUtilTest.java:10) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)Caused by: org.h2.jdbc.JdbcSQLNonTransientConnectionException: Database may be already in use: "C:/Users/SeoCom1/testDB.mv.db". Possible solutions: close all other connection(s); use the server mode [90020-224] at org.h2.message.DbException.getJdbcSQLException(DbException.java:690) at org.h2.message.DbException.getJdbcSQLException(DbException.java:489) at org.h2.message.DbException.get(DbException.java:212) at org.h2.mvstore.db.Store.convertMVStoreException(Store.java:165) at org.h2.mvstore.db.Store.<init>(Store.java:142) at org.h2.engine.Database.<init>(Database.java:326) at org.h2.engine.Engine.openSession(Engine.java:92) at org.h2.engine.Engine.openSession(Engine.java:222) at org.h2.engine.Engine.createSession(Engine.java:201) at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:343) at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:125) at org.h2.Driver.connect(Driver.java:59) at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:681) at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:229) at hello.jdbc.connection.DBConnectionUtil.getConnection(DBConnectionUtil.java:11) ... 4 moreCaused by: org.h2.mvstore.MVStoreException: The file is locked: C:/Users/SeoCom1/testDB.mv.db [2.2.224/7] at org.h2.mvstore.DataUtils.newMVStoreException(DataUtils.java:996) at org.h2.mvstore.SingleFileStore.lockFileChannel(SingleFileStore.java:143) at org.h2.mvstore.SingleFileStore.open(SingleFileStore.java:117) at org.h2.mvstore.SingleFileStore.open(SingleFileStore.java:81) at org.h2.mvstore.MVStore.<init>(MVStore.java:286) at org.h2.mvstore.MVStore$Builder.open(MVStore.java:2035) at org.h2.mvstore.db.Store.<init>(Store.java:133) ... 14 moreProcess finished with exit code -1 이렇게 코드가 나오는데Caused by: org.h2.jdbc.JdbcSQLNonTransientConnectionException: Database may be already in use: "C:/Users/SeoCom1/testDB.mv.db". Possible solutions: close all other connection(s); use the server mode [90020-224]<-이 부분이 원인이 되는 이유인 것 같더라고요.... 구글링으로 최대한 해결해보려고 했는데 결국 어떻게 바꿔야할지 감이 잡히지 않습니다.
-
미해결스프링 DB 1편 - 데이터 접근 핵심 원리
Lock에 대해서 궁금한점이 있습니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]기본적인 Lock설정시에 해당 레코드의 update 쿼리나 혹은 수정쿼리가 발생할경우에는 commit되기전까지는 접근이 안된다고하셨는데그러면 만약에 update set money=(select money from member where member_id='memberA')-3000 where member_id='memberA'아예 update내부의 select문도 실행되지않는 상태로 존재하는건가요?
-
해결됨스프링 DB 1편 - 데이터 접근 핵심 원리
ResultSet의 cursor에 관해서 궁금한게 있습니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]curosr부분에 대해서 궁금한점이 있습니다 해당 부분에서 커서를 이동시키면서 데이터를 가지고온다고 이해하였는데 데이터베이스에서 웹애플리케이션서버로 데이터를 가지고올때 전체 결과 집합을 웹어플리케이션서버에서 가지고온뒤 웹어플리케이션서버에서 커서를 사용해서 데이터를 하나씩 뽑아오는 방식인가요?아니면 커서하나를 내릴때마다 네트워크 요청을 통해서 데이터베이스서버와 통신하여 한줄씩 데이터를 받아오는건가요?
-
해결됨스프링 DB 1편 - 데이터 접근 핵심 원리
close()에 관해 궁금한점이 있습니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]Connection 객체의 경우에는 해당 커넥션이 만들어지고 close하지않으면 네트워크 리소스 소모때문에 close를 해야하는것으로 이해했습니다.그렇다면 preparedStatement와 ResultSet객체의 경우에는 해당 데이터베이스로 SQL문을 전송및 전달받는 객체인걸로 보이는데 왜 close로 명시적으로 닫아야하는건가요?
-
미해결스프링 DB 1편 - 데이터 접근 핵심 원리
예외처리 질문
try { Thread.sleep(1000); } catch (InterruptedException e) { throw new RuntimeException(e); } 이 코드를 실행하면 왜 밑에있는 출력문이 10개가 나오는지 궁금합니다 HikariPool-1 connection adder] DEBUG com.zaxxer.hikari.pool.HikariPool -- HikariPool-1 - Added connection conn1: url=jdbc:h2:tcp://localhost/~/test user=SA
-
해결됨스프링 DB 1편 - 데이터 접근 핵심 원리
rs.next()의 동작 방식이 궁금합니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]ResultSet에서 데이터를 얻어오기 위해 rs.next()를 계속 수행하며 진행하는데 여기에서 궁금한게ResultSet은 첫 쿼리로 모든 데이터를 받아온 뒤에 단순히 메모리에서 커서를 이동하는 건가요?아니면 rs.next()가 호출될때마다 DB에서 새로 데이터를 받아오는건가요?
-
미해결스프링 DB 1편 - 데이터 접근 핵심 원리
get connection 로그가 6개 나오는 이유가 궁금해요
여기 로그를보면 get connection 로그가 6개가나오는데요 save ,findById, update, delete 4번을해서 로그가 4번이 나올줄알았는데 왜 커넥션로그가 6번 나왔는지 궁금해요
-
미해결스프링 DB 1편 - 데이터 접근 핵심 원리
ConnectException이 잡히지 않는 이유
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]checked() 테스트에서 아래와 같이 isInstanceOf(SQLException.class)를 ConnectException.class로 변경하면 왜 테스트가 통과되지 않는지 궁금합니다 ! @Test void checked() { Controller controller = new Controller(); Assertions.assertThatThrownBy(() -> controller.logic()) .isInstanceOf(ConnectException.class); }public void logic() throws SQLException, ConnectException { service.logic(); } service.logic()에서 두 예외가 다 밖으로 던져졌으니 테스트에서도 ConnectException가 발생하는게 아닌가요?
-
해결됨토비의 스프링 부트 - 이해와 원리
4섹션 스프링컨테이너로 통합 재생이 안됩니다.
계속 무한 로딩만 뜨고 재생이 안됩니다. ㅠ+같은 섹션 'SpringBootApplication' 도 재생이 안되고 있습니다.
-
미해결스프링 DB 1편 - 데이터 접근 핵심 원리
TransactionSynchronizationMaganger 질문
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]안녕하세요~ repository은 TransactionSynchronizationMaganger를 통해 트랜잭션이 적용되어 기존의 커넥션이 존재하면 그 커넥션을, 트랜잭션이 적용되어 있지 않아 기존의 커넥션이 없으면 새로운 커넥션을 받아올텐데요. 트랜잭션이 적용되어 기존의 커넥션이 존재할 때, 그 기존의 커넥션을 식별할 수 있는 방법은 무엇인가요? 즉, TransactionSynchronizationMaganger는 각 서비스에서 사용중인 커넥션들을 어떻게 식별해서 각 서비스에 전달하는지 궁금합니다.
-
미해결토비의 스프링 부트 - 이해와 원리
어노테이션매핑정보 - 404 오류 문의드립니다
안녕하세요. 어노테이션 매핑정보 사용 강의 보고 궁금한점이 생겨 문의 남겼습니다.지금까지 강의에 나온것과 똑같이 코드를 작성했습니다. 그런데 실행하면 예상했던 값이 나오지 않고 404 오류가 떠요.실행창에는 아래와 같은 메세지가 나옵니다.16:09:26.879 [http-nio-8080-exec-1] WARN org.springframework.web.servlet.PageNotFound -- No mapping for GET /hello16:09:26.886 [http-nio-8080-exec-1] WARN org.springframework.web.servlet.PageNotFound -- No endpoint GET /hello. 그래서 HelloController 클래스위에 @RequestMapping을 지우고 대신 @Controller을 추가해봤더니 그제서야 강의와 같은 결과가 나옵니다.제 스프링 버전은 3.x, jdk17인데 이것과 관련이 있을까요? 같은 코드인데 왜 저는 404가 나오는지 궁금합니다...
-
해결됨스프링 DB 1편 - 데이터 접근 핵심 원리
트랜잭션 동작 원리 정리
트랜잭션의 동작 원리에 대해서 정리해봤습니다.제대로 이해했는지 확인 부탁드립니다! 혹시 잘못 이해하고 있는 부분이 있다면 말씀 부탁드립니다. 서비스 클래스의 메소드에 @Transactional 이 있으면 스프링은 해당 비즈니스 로직을 상속한 AOP 프록시 객체를 생성한 후, 이를 스프링 빈에 등록한다.클라이언트가 해당 프록시를 호출한다. (비즈니스 로직 자체를 호출하지 않는다)스프링은 스프링 컨테이너에 등록된 트랜잭션 매니저를 획득한다.트랜잭션 매니저의 transactionManager.getTransaction()을 호출하여 트랜잭션을 시작한다.트랜잭션 매니저는 스프링 컨테이너에 등록된 데이터 소스를 이용하여 커넥션을 생성한다.커넥션의 con.setAutoCommit(false) 호출로 수동 커밋 모드로 변환한다.생성하고 설정을 끝낸 커넥션을 트랜잭션 동기화 매니저에 보관한다.실제 서비스를 호출하면, 서비스의 비즈니스 로직과 리포지토리의 데이터 접근 로직이 수행된다.리포지토리의 데이터 접근 로직은 트랜잭션 동기화 매니저에 보관된 커넥션을 획득한 후 DB에 접근하여 SQL을 수행한다.비즈니스 로직이 끝나면서 AOP 프록시에서 커밋 또는 롤백을 통해 트랜잭션을 종료한다.트랜잭션을 종료함으로써 커넥션은 커넥션 풀에 반납된다.
-
해결됨스프링 DB 1편 - 데이터 접근 핵심 원리
프록시 객체 생성은 @Transactional 메소드 단위인가요?
프록시에 대해서 잘 모르는 상태로 질문드립니다.앞으로 다른 강의에서 나올 수 있는 내용이지만, 일단 큰 그림을 잡을 수 있게 간단하게 질문드립니다. 이번 강의에서 메소드에 @Transactional을 붙이면 프록시 객체가 만들어진다고 배웠습니다.그렇다면 @Transactional가 붙어있는 메소드 단위로 프록시 객체가 만들어지는 건지, 아니면 Service 클래스 단위로 프록시 객체가 만들어지는 건지 궁금합니다.예를 들어, Service 클래스에 3개의 메소드가 있다고 가정했을 때, @Transactional 메소드가 2개, 일반 메소드가 1개 있다면, 프록시 객체는 2개가 만들어지는 건가요? 아니면 한 개의 프록시 객체에 두 개의 메소드가 등록되는 건가요?
-
미해결스프링 DB 1편 - 데이터 접근 핵심 원리
이체중 예외 발생 테스트에서 롤백이 안되는 것 같아요
프로젝트 코드 : https://drive.google.com/file/d/11CCB36D9oTLIXMvT4LUcGoXfyXB9Pk0E/view?usp=sharing MemberSerivceV3_1Test, MemberSerivceV3_2Test 에서 이체중 예외 발생 테스트가 통과가 안됩니다.기대하는 바는 롤백이 적용되어야 하는데, 실제 값은 롤백이 적용되지 않는 8000원이 저장됩니다.PlatformTransactionManager을 적용한 코드에서 문제가 발생하는 것 같습니다.딱히 놓친 부분이나 잘못한 부분을 발견하기 힘들어서 도움을 요청드리고자 질문 올립니다. ㅠㅠ 감사합니다.