작성
·
497
0
안녕하세요 질문이 있어서 글을 남깁니다.
현재 저는 다중 데이터베이스 기반의 배치 Call 서버를 제작중에 있습니다.
한개의 데이터베이스는 Batch Metadata 저장 서버로, 다른 서버를 Datasource로 가져와서 ItemReader 나 Writer 로 사용하고 있습니다(2개의 datasource 지정)
다중서버 구성시 JpaItemWriter를 이용하게 되면, repository의 트랜잭션 보장 문제로 인하여 'no transaction in progress'문제가 생겼고, 해당 문제 확인 결과 stepBuilderFactory.transcationManager(PlatformTransactionManager)으로 다중 datasource에 writer를 처리할 수 있음을 알게 되었습니다.
async방식의 처리에서 AsyncItemWriter도 같은 방식으로 transactionManager를 처리하였는데, 두가지의 문제가 발생하였습니다.
1) AsyncItemWriter에서 delegate시에 transactionManager 이 적용이 안되는지, 'no transaction is in progress' 가 발생합니다. 제가 주입하고자 하는 transactionManager가 적용이 안되고 delegate시 알아서 시스템이 자동 주입을 하는거 같은데, 해당 현상에 대한 해결방법을 알고싶습니다.
* 해당 현상에 대한 에러는 하단에 남깁니다. ItemWriter 구현체는 JpaItemWriter입니다
2) 강사님의 강의에서도 나온 문제인데, StepBuilderFactory 반환에서 Warning이 발생하고 있습니다.(AsyncItemWriter 강의 21:50경) 타입을 체크하지 않고 발생하는 오류인데, 타입을 제대로 주면 Future때문인지 명확하게 warning이 해결되지 않고 있습니다. 이건 어노테이션으로 워닝 무시를 해야할 수 밖에 없는 것인지 알고 싶습니다.
* 아마도 stepbuildFactory의 <input, output> 값이 <InputEntity, Future<OutputEntity>> 가 되어야 하는 것이 맞아보이는데 맞는지요?
에러)
22:51 INFO o.s.batch.core.job.SimpleStepHandler - Executing step: [asyncInitializationStep1]
22:51 ERROR o.s.batch.core.step.AbstractStep - Encountered an error executing step asyncInitializationStep1 in job initializationJob
javax.persistence.TransactionRequiredException: no transaction is in progress
at org.hibernate.internal.AbstractSharedSessionContract.checkTransactionNeededForUpdateOperation(AbstractSharedSessionContract.java:445)
at org.hibernate.internal.SessionImpl.checkTransactionNeededForUpdateOperation(SessionImpl.java:3478)
at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1394)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1389)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:362)
at com.sun.proxy.$Proxy137.flush(Unknown Source)
at org.springframework.batch.item.database.JpaItemWriter.write(JpaItemWriter.java:94)
at org.springframework.batch.integration.async.AsyncItemWriter.write(AsyncItemWriter.java:85)
at org.springframework.batch.core.step.item.SimpleChunkProcessor.writeItems(SimpleChunkProcessor.java:193)
at org.springframework.batch.core.step.item.SimpleChunkProcessor.doWrite(SimpleChunkProcessor.java:159)
at org.springframework.batch.core.step.item.SimpleChunkProcessor.write(SimpleChunkProcessor.java:294)
at org.springframework.batch.core.step.item.SimpleChunkProcessor.process(SimpleChunkProcessor.java:217)
at org.springframework.batch.core.step.item.ChunkOrientedTasklet.execute(ChunkOrientedTasklet.java:77)
at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:407)
at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:331)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140)
at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:273)
at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:82)
at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:375)
at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215)
at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:145)
at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:258)
at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:208)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:137)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:124)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215)
at com.sun.proxy.$Proxy148.execute(Unknown Source)
at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:152)
at org.springframework.batch.core.job.AbstractJob.handleStep(AbstractJob.java:413)
at org.springframework.batch.core.job.SimpleJob.doExecute(SimpleJob.java:136)
at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:320)
at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:149)
at java.base/java.lang.Thread.run(Thread.java:829)
22:51 INFO o.s.batch.core.step.AbstractStep - Step: [asyncInitializationStep1] executed in 9s902ms
22:51 INFO o.s.b.c.l.support.SimpleJobLauncher - Job: [SimpleJob: [name=initializationJob]] completed with the following parameters: [{firmCode=0001, fileType=fixed, executeDate=1646661075421}] and the following status: [FAILED] in 9s960ms