월 19,800원
5개월 할부 시다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결스프링 배치
젠킨스 스케줄
안녕하세요.실무 코드만 보고 배치를 만들다가 제대로 이해하고 써보자는 생각에 강의를 듣게 되었는데 제대로 배우고 있어서 너무 유익하게 보고 있습니다.ㅎㅎ제가 아직은 배치를 깊이 있게 아는 것은 아니라 기본적인 질문일 수도 있지만.. 실무에서 젠킨스 스케줄 설정을 통해 같은 파라미터의 Job 을 매 시간마다 실행시키고 있습니다.그런데 동일한 Job + JobParameter 의 경우 재실행이 불가능한 것으로 배우고 있는데, 젠킨스 스케줄의 경우에는 예외인걸까요!?(incrementer() 없이 단순한 start(), next() 구성의 배치입니다.)
- 미해결스프링 배치
롤백 관련 질문드립니다.
여러 스탭을 포함한 Job을 실행하는 과정에서 Job이 실패하면 실패하기 전까지는 커밋이 되는데, 그게 아니라 Job이 실패하면 Job이 실행하시 전으로 롤백할 수도 있나요?
- 미해결스프링 배치
트랜잭션 관련 질문드립니다.
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 안녕하세요, 이전에 트랜잭션 범위 질문 관련하여 추가 질문드리려고 합니다 :) 단일 tasklet에서 여러 테이블을 update할 때 하나를 업데이트하고 뒤에서 오류가 나면 롤백이 안되는데 보통 실무에서 어떻게 사용하는지 궁금합니다.예를 들면 아래와 같이 하나의 tasklet 내에서 2개의 업데이트 작업이 필요하고, 이 두 테이블 업데이트가 하나의 트랜잭션에 묶여야 할 때 어떤식으로 작업을 주로 하는지 궁금합니다.new tasklet() { // 테이블1 업데이트 로직 table1Service.update(); // 오류 발생 throw new RuntimeException("오류 발생"); // 테이블2 업데이트 로직 table2Service.update(); }(chunk 단위로 업데이트할 정도로 업데이트할 양이 많지 않아 따로 itemReader/itemProcess/itemWriter 구현을 하지 않은 단일 tasklet 예시입니다)그리고, 테이블 업데이트 로직이 다른 서비스 로직을 호출하여서 업데이트하는것이라면 해당 서비스 로직의 transaction에 springbatch가 만들어준 transaction이 전파되지 않는 이유가 궁금합니다. step 실행을 함으로써 springbatch가 생성해준 트랜잭션 내부에서 서비스를 호출하여서 해당 트랜잭션이 전파되어서 서비스의 트랜잭션이 자식 트랜잭션이 될 것이라 생각하였는데, 실제로 테스트했을 때 각각 따로 트랜잭션 처리가 되어 롤백이 제대로 이루어지지 않는 것으로 보여서 문의드립니다.
- 미해결스프링 배치
Fetch와 Cursor의 순서?
[DB - Cursor & Paging 이해] 강의에서 보여주신 장표를 보면 cursot가 먼저 움직이고 fetch를 통해 application으로 매핑된 데이터(객체)를 넘겨주는 것처럼 표현되어있는데요.fetch size에 의해서 DB --> 메모리로 데이터가 적재된 후, 그 결과집합을 순차적으로 cursor를 통해 접근하는걸로 알고있습니다.즉, fetch size는 DB에서 메모리로 데이터를 적재할 크기이고 그 데이터 셋을 처음부터 cursor를 통해 접근하는게 맞지않나 싶어서 질문드립니다. 제가 반대로 알고 있을 수 있지만...
- 미해결스프링 배치
Flow 생성 시, flowBuilder에 end()와 build()를 각각 호출하는 이유
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.안녕하세요, FlowJob 관련하여서 궁금한 점이 있어 문의드립니다.강의 중에 아래와 같이 작성된 코드가 있었는데요. @Bean public Flow flow() { FlowBuilder<Flow> flowBuilder = new FlowBuilder<>("flow"); flowBuilder.start(step1()) .next(step2()) .end(); return flowBuilder.build(); }FlowBuilder 내 end() 메소드를 살펴보면, end() 메소드 내에서 this.build()를 호출하는 것으로 보이는데요. public final Q end() { return this.build(); } 하기와 같이 작성하지 않고 위처럼 end()와 build()를 각각 쓰는 사유가 있는지 궁금합니다.@Bean public Flow flow() { FlowBuilder<Flow> flowBuilder = new FlowBuilder<>("flow"); return flowBuilder.start(step1()) .next(step2()) .end(); } 새해 복 많이 받으세요 :)
- 미해결스프링 배치
ItemWriter 재사용 관련 질문입니다.
ItemWriter 를 다른 Job Configuration 파일에서도 재사용하고 싶은데 방법이 있을까요? 예를 들어 아래와 같은 ItemWriter가 SampleJob1Configuration.class 에 있고, SampleJob2Configuration.class에서 재사용이 가능한지 궁금합니다. @Bean(name = "jdbcItemWriter") public JdbcBatchItemWriter<AccessApiDto> jdbcItemWriter() { return new JdbcBatchItemWriterBuilder<AccessApiDto>() .dataSource(TargetDataSourceManager.targetDataSource) .sql("insert into ~") .beanMapped() .build(); } 혹시 @Component로 등록하는 방법이 있을까요?
- 미해결스프링 배치
Repositoryitemreader로 조회한 데이터 dirty check 여부 질문
안녕하세요~ 강사님 강의를 보고 스프링 배치 입문해서 열심히 이론부터 실습까지 잘 배우고 있습니다.몇 가지 궁금한 점이 있어서 이렇게 질문을 드리게 되었습니다.1.ItemReader 중에 Repositoryitemreader라는 구현체가 있어서 이게 Spring Data JPA를 지원해 줘서 사용해 보았는데요. 이해가 가지 않는 부분이 있어서 질문드리고자 합니다. @Bean(name = STEP_NAME) @JobScope public Step step1(@Value("#{jobParameters[chunkSize]}") Long chunkSize) { return stepBuilderFactory.get(STEP_NAME) .<HistoryEntity, HistoryEntity>chunk(chunkSize.intValue()) .reader(itemReader(null)) .processor(itemProcessor()) .writer(itemWriter()) .build(); } @Bean(name = JOB_NAME + "_reader") @StepScope public RepositoryItemReader<HistoryEntity> itemReader(@Value("#{jobParameters[chunkSize]}") Long chunkSize) { LocalDateTime now = LocalDateTime.now(); return new RepositoryItemReaderBuilder<HistoryEntity>() .name(JOB_NAME + "_reader") .repository(HistoryPagingCrudRepository) .methodName("findByLeaveDtLessThanEqual") .pageSize(chunkSize.intValue()) .arguments(List.of(now)) .sorts(Collections.singletonMap("leaveDt", Sort.Direction.DESC)) .build(); }위와 같은 step과 특정 날짜의 데이터를 조회하는 ItemReader를 구현한 후 아래 ItemWriter 에서 @Bean(name = JOB_NAME + "_writer") @StepScope public ItemWriter<HistoryEntity> itemWriter() { return item -> { item.forEach(historyEntity -> { // Id 값을 null로 만드는 메소드 historyEntity.updateRemoveId(); } ); }; }Entity의 값을 변경하게 되면 당연히 하나의 chunk 단위에서는 하나의 트랜잭션 이기 때문에 JPA의 dirty check로 인한 Id 값을 지우는 update 쿼리가 나갈거라고 생각했는데 그렇지 않더라고요.다만, @Bean(name = JOB_NAME + "_writer") @StepScope public ItemWriter<HistoryEntity> itemWriter() { return item -> { item.forEach(historyEntity -> { // Id 값을 null로 만드는 메소드 historyEntity.updateRemoveId(); historyPagingCrudRepository.save(historyEntity) } ); }; }위 코드 historyPagingCrudRepository.save(historyEntity) 를 추가하면 merge가 진행되면서 update 쿼리가 실행되긴 하지만 select 쿼리가 한 번 더 실행돼서 비효율적인거 같다는 생각이 들었습니다.질문을 정리하자면 ItemReader에서 조회한 Entity가 ItemWriter에서도 영속 상태이기 때문에 Dirty Checking 대상이라고 생각했는데 그렇지 않은 이유가 무엇인가요??혹시 ItemReader 로 데이터 조회 후 ChunkProvider를 통해 Chunk<I> 를 itemProcessor 또는 ItemWriter로 전달하는 과정에서 준영속 상태가 되는것일까요?? 2.jpaPagingItemReader 으로 데이터 조회 후, ItemWriter 에서 jpaPagingItemReader 의 where 절에 해당하는 컬럼의 값을 수정했을 때 offset(page)로 인해 일부 데이터가 읽히지 않는 문제가 있는것으로 알고있습니다. 이 경우 getPage() 메소드를 override 해서 항상 offset을 0으로 고정시키는 방법으로 해결이 가능한데 Repositoryitemreader 구현체 사용 시 어떤식으로 해결이 가능할까요??
- 미해결스프링 배치
트랜잭션 범위 질문
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 안녕하세요,TaskletStep - 개념 및 API 소개 수강하면서 궁금한 점이 있어 여쭤보고자 합니다. TaskletStep의 경우 트랜잭션 경계 내에서 수행되며, 따로 트랜잭션 처리를 하지 않아도 SpringBatch에서 알아서 트랜잭션 설정을 해주는 것으로 이해를 하였는데요. 만약, TaskletStep 내에 커스텀하게 만든 Tasklet 속에서 Service(@Transactional 어노테이션이 붙은)를 호출하게 된다면, 이 서비스 로직은 TaskletStep의 트랜잭션 내에 트랜잭션이 또 생겨서 독립적으로(?) 움직이는 것인지 궁금합니다. 답변 기다리겠습니다. 감사합니다.
- 미해결스프링 배치
안녕하세요. 질문드립니다.
안녕하세요. 강의 잘 듣고 있습니다.사소한 부분일 수 있지만 ppt 56 페이지 도식에서 StepExecutionID 가 5인 StepExecution은 StepExecutionID 3에서 성공했으니 생성되지 않는게 아닌가요 ?제가 잘못 생각하고 있는 거라면 답변 부탁드립니다.
- 미해결스프링 배치
섹션 8. 스프링 배치 청크 프로세스 활용 - ItemReader - DB - JdbcCursorItemReader 디버그로그 관련
섹션 8. 스프링 배치 청크 프로세스 활용 - ItemReader - DB - JdbcCursorItemReader관련으로 문의 드립니다.(https://github.com/onjsdnjs/spring-batch-lecture/tree/Part6.1.4.1 => 소스 찾기 힘드네요... 섹션은 8인데 소스는 part6라늬...) 강의 내용 따라서 진행하다가 오류 발생하여 github에 업로드된 소스로 직접 돌려봤으나 강의 내용처럼 job 실행은 안되고 위의 캡쳐 이미지처럼만 나오고 끝나더라구요.소스는 강사님께서 업로드해주신 소스 그대로입니다.혹시 추가 작업이 필요로 할까요?
- 미해결스프링 배치
H2 DATABASE
h2 DATABASE 연결은 강의 챕터 어디에서 설명이 나와있나요? mysql은 연결해서 yml 작성하다가 h2는 내용에없는데 제가 못본것 같아서 여쭤봅니다
- 미해결스프링 배치
multi datasource에서의 jobRegistryBeanPostProcessor
안녕하세요, 회사에서 배치 업무 개발로 인해 현재 이 강의를 수강하고 있습니다.강의는 다 수강하지 못하였지만, 배치 개발 중에 문제가 발생하여 질문 드립니다. 배치 프로젝트에 단일 datasource일 때에는,jobRegistryBeanPostProcessor가 정상 작동합니다. 하지만, multiple datasource로 설정후에jobRegistryBeanPostProcessor를 bean으로 등록시에는datasource 관련 설정 값들을 읽어드리지 못하여(@Value annotation을 이용하여 config.yml에서 읽어드리는데, null value return함)서버가 구동조차 하지 않습니다. 서버가 구동하지 않아서 debug도 못하는 상황입니다..아무리 구글링하여도 원인조차 찾을 수 없어 답답한 마음에 질문남깁니다.
- 미해결스프링 배치
멀티스레드 속도 질문입니다
setCorePoolSize 2, setMaxPoolSize 8 일 때 블락 등이 발생하지 않아서 2개로만 동작한다고 하셨습니다.cpu 하나가 2개 스레드를 번갈아가면서 동작시킬텐데요. 오히려 싱글스레드보다 context switching시간만 추가되어서 처리속도가 더 늘어나야 되지 않나 싶어요. 이유를 알 수 있을까요??
- 미해결스프링 배치
v5는 많은 것이 바뀌어서 test해보려는데 왜 Tasklet에 있는 System.out.println는 실행되지 않을까요??
v5로 test해보려는데 왜 Tasklet의 System.out.println는 찍히지 않는 걸까요??package me.victorsung.demobatch; import org.springframework.batch.core.Job; import org.springframework.batch.core.Step; import org.springframework.batch.core.StepContribution; import org.springframework.batch.core.configuration.support.DefaultBatchConfiguration; import org.springframework.batch.core.job.builder.JobBuilder; import org.springframework.batch.core.repository.JobRepository; import org.springframework.batch.core.scope.context.ChunkContext; import org.springframework.batch.core.step.builder.StepBuilder; import org.springframework.batch.core.step.tasklet.Tasklet; import org.springframework.batch.repeat.RepeatStatus; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.transaction.PlatformTransactionManager; @Configuration public class HelloJobConfiguration extends DefaultBatchConfiguration { @Bean public Job myJob(JobRepository jobRepository, Step myStep1, Step myStep2) { System.out.println("this is job"); return new JobBuilder("myJob", jobRepository) .start(myStep1) .next(myStep2) .build(); } @Bean public Step myStep1(JobRepository jobRepository, Tasklet myTasklet1, PlatformTransactionManager transactionManager) { System.out.println("this is step1"); return new StepBuilder("myStep1", jobRepository) .tasklet(myTasklet1, transactionManager) .build(); } @Bean public Step myStep2(JobRepository jobRepository, Tasklet myTasklet2, PlatformTransactionManager transactionManager) { System.out.println("this is step2"); return new StepBuilder("myStep2", jobRepository) .tasklet(myTasklet2, transactionManager) .build(); } @Bean public Tasklet myTasklet1() { System.out.println( """ this is myTasklet1 """ ); // Step에서는 Tasklet을 무한 반복 시킨다. 그래서 RepeatStatus을 null || RepeatStatus.FINISHED로 주어야 한번 실행하고 끝난다. return new Tasklet() { @Override public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception { System.out.println( """ myTasklet1 ============================================== >> contribution = %s >> chunkContext = %s ============================================== """.formatted(contribution, chunkContext) ); return RepeatStatus.FINISHED; } }; } @Bean public Tasklet myTasklet2() { System.out.println("this is taskLet2"); // Step에서는 Tasklet을 무한 반복 시킨다. 그래서 RepeatStatus을 null || RepeatStatus.FINISHED로 주어야 한번 실행하고 끝난다. return (contribution, chunkContext) -> { System.out.println("test2"); System.out.println( """ myTasklet2 ============================================== >> contribution = %s >> chunkContext = %s ============================================== """.formatted(contribution, chunkContext) ); return RepeatStatus.FINISHED; }; } } . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v3.0.0) 2022-12-06T11:11:34.542+09:00 INFO 87250 --- [ main] m.v.demobatch.DemoBatchApplication : Starting DemoBatchApplication using Java 17.0.4.1 with PID 87250 (/Users/victor/Documents/thecommerce/demo-batch/out/production/classes started by victor in /Users/victor/Documents/thecommerce/demo-batch) 2022-12-06T11:11:34.544+09:00 INFO 87250 --- [ main] m.v.demobatch.DemoBatchApplication : No active profile set, falling back to 1 default profile: "default" 2022-12-06T11:11:34.671+09:00 INFO 87250 --- [ main] o.s.b.c.c.annotation.BatchRegistrar : Bean jobRepository already defined in the application context, skipping the registration of a jobRepository 2022-12-06T11:11:34.671+09:00 INFO 87250 --- [ main] o.s.b.c.c.annotation.BatchRegistrar : Bean jobExplorer already defined in the application context, skipping the registration of a jobExplorer 2022-12-06T11:11:34.671+09:00 INFO 87250 --- [ main] o.s.b.c.c.annotation.BatchRegistrar : Bean jobLauncher already defined in the application context, skipping the registration of a jobLauncher 2022-12-06T11:11:34.671+09:00 INFO 87250 --- [ main] o.s.b.c.c.annotation.BatchRegistrar : Bean jobRegistry already defined in the application context, skipping the registration of a jobRegistry 2022-12-06T11:11:34.671+09:00 INFO 87250 --- [ main] o.s.b.c.c.annotation.BatchRegistrar : Bean jobOperator already defined in the application context, skipping the registration of a jobOperator 2022-12-06T11:11:34.671+09:00 INFO 87250 --- [ main] o.s.b.c.c.annotation.BatchRegistrar : Finished Spring Batch infrastructure beans configuration in 0 ms. 2022-12-06T11:11:34.784+09:00 WARN 87250 --- [ main] ocalVariableTableParameterNameDiscoverer : Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead or avoid its introspection: me.victorsung.demobatch.HelloJobConfiguration 2022-12-06T11:11:34.811+09:00 INFO 87250 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... 2022-12-06T11:11:34.891+09:00 INFO 87250 --- [ main] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:06a2d6ef-e350-45b8-8468-33c43eb10333 user=SA 2022-12-06T11:11:34.891+09:00 INFO 87250 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. this is myTasklet1 this is step1 2022-12-06T11:11:34.922+09:00 INFO 87250 --- [ main] .c.a.BatchObservabilityBeanPostProcessor : No Micrometer observation registry found, defaulting to ObservationRegistry.NOOP this is taskLet2 this is step2 2022-12-06T11:11:34.923+09:00 INFO 87250 --- [ main] .c.a.BatchObservabilityBeanPostProcessor : No Micrometer observation registry found, defaulting to ObservationRegistry.NOOP this is job 2022-12-06T11:11:34.925+09:00 INFO 87250 --- [ main] .c.a.BatchObservabilityBeanPostProcessor : No Micrometer observation registry found, defaulting to ObservationRegistry.NOOP 2022-12-06T11:11:34.985+09:00 INFO 87250 --- [ main] m.v.demobatch.DemoBatchApplication : Started DemoBatchApplication in 0.659 seconds (process running for 0.901) 2022-12-06T11:11:34.988+09:00 INFO 87250 --- [ionShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated... 2022-12-06T11:11:34.990+09:00 INFO 87250 --- [ionShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed. Process finished with exit code 0
- 미해결스프링 배치
43:07 skip 질문입니다.
ItemWriter에서 '12' 아이템이 예외가 터져서 Skip처리 되고, 다시 ItemReader 부터 재실행 되는 것은 이해했습니다.근데 ItemProcessor에서 '6'과 '7' 을 Skip처리한 거처럼ItemWriter역시 마찬가지로 ExecutionContext에 '12' 아이템이 저장되므로 ItemProcessor와 ItemWriter에서 '12' 아이템은 Skip 해야 되지 않나요? 그러면 출력값에 6, -6과 7, -7이 안뜬거 처럼12, -12는 안떠야 된다고 생각합니다.
- 미해결스프링 배치
JobStep 강의에서 childJob() 실행 질문
job: names: ${job.name:NONE}설정하고 --job.name=parentjob 설정했습니다.그럼 parentJob실행이 됩니다.근데 childJob은 왜 실행되는건가요? joblauncher 값을 null 로 주어서 인가요?
- 미해결스프링 배치
Chunk 방식에 관하여 질문드립니다!
안녕하세요. SpringBatch Chunk 관련해서 궁금한점이 생겨서 질문드립니다!보통 하나의 Step에 ItemReader,ItemProcessor,ItemWriter가 1:1:1 구조로 설계되는걸 코드로 보았습니다.만약에 Chunk 기능은 그대로 사용하고 싶으면서, ItemReader는 2번, ItemProcessor,ItemWrite는 1번씩만 구현하고 싶다면 어떤 방법이 좋을까요?(ItemReader에서 각각 List 데이터를 읽어온다음에, Process에서 가공하고, ItemWriter에 chunk단위로 가공한 데이터를 insert 하고 싶음을 의미합니다)강의 잘 듣고 있습니다. 날이 추우신데 건강 조심하세요!
- 미해결스프링 배치
itemProcessor내에서 mybatis를 이용해 db를 조회하고 싶은대요
itemProcessor내에서 mybatis를 이용해 db를 조회하고 싶은대요 그렇게도 할 수 있는건가요? 어떻게 해야하는건지요
- 미해결스프링 배치
멀티 스레드 적용 방식 차이가 있나요?
이전 강의:AsyncItemProcessor, AsyncItemWriter 구현체 적용하는 방식현재 강의:TaskExecutor 구현체 적용하는 방식 요 두가지 방식에서 기능+성능 차이가 있을까요?단순히 적용 방식 차이 뿐인지 궁금합니다
- 미해결스프링 배치
강의자료 다운로드 문의
안녕하세요~ 강의 잘 듣고 있습니다.교육과정 목차 상단에 강의자료 및 파일다운로드 기능이 있다고 하는데...제 화면에서는 안보이는데 강의자료가 별도로 제공되지 않는건가요?