ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • spring batch reader에서 transaction read mode로 실행하기
    spring 2020. 5. 21. 20:26
    반응형

    현재 검색 spring batch는 reader에서 db select시 write mode로 동작됩니다.

    모든 것이 그런것은 아니고 chunk oriented batch에서 그렇게 돌아가게 되는데요

    배치가 많아질 수록 가져와야 하는 데이터 양이 많아질 수록 write mode = master db로 부하를 주기 때문에

    read mode = slave db로 타게 만들어줘야 할 필요성이 생겨 변경하는 작업을 하였습니다

    reader, processor, writer 3개가 한개의 트랜잭션으로(write mode) 묶이며 chunk size 기준으로 rollback되기 때문에

     

    reader에서 새로운 트랜잭션을 열어줘야 됩니다.

    그래서 추가한 작업은 

    QuerydslItemReader.class

     

    jpasqlCustomQuery.offset(page * pageSize).limit(pageSize);
    List fetch = jpasqlCustomQuery.fetch();



    를 아래와 같이 변경하고 추가하였습니다.

    List fetch = TransactionUtils.executeReadMode(jpasqlCustomQuery, status -> {
    	jpasqlCustomQuery.offset(page * pageSize).limit(pageSize);
    	log.info("Transaction readonly flag: {}",
    	TransactionSynchronizationManager.getCurrentTransactionName());
    
    	log.info("Transaction readonly flag: {}",
    	TransactionSynchronizationManager.isCurrentTransactionReadOnly());
    	return jpasqlCustomQuery.fetch();
    });



    TransactionUtils.class

    public class TransactionUtils {
    
    	public static List executeReadMode(JpaSqlCustomQuery jpaSqlCustomQuery, TransactionCallback<List> action) {
    		TransactionTemplate transactionTemplate = new TransactionTemplate();
    		transactionTemplate.setReadOnly(true);
    		transactionTemplate.setTransactionManager(jpaSqlCustomQuery.getTransactionManager());
    		transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
    		transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_READ_UNCOMMITTED);
    
    		List fetch = transactionTemplate.execute(action);
    
    		return fetch;
    	}
    }



    주의해야 할 부분은 새로운 트랜잭션을 오픈하기때문에 롤백되지 않은 문제가 있을 수 있습니다


    StyleCreateBatch.class

    @Resource(name = "x")
    private final PlatformTransactionManager x;
    
    @Bean
    @JobScope
    public Step bulkStylesForCreateStep(@Value("#{jobParameters[x]}") String x) throws Exception {
    
    	return stepBuilderFactory
    		.get("x")
    		.transactionManager(x)
    		.<x, x>chunk(batchSize)
    		.reader(x())
    		.processor(x)
    		.writer(x)
    		.build();
    }
    
    


    x를 transactionManager에 추가해줍니다!

     

    사실 글 하나하나 쓰는 것에 공을 드리고 싶은데 정말 쉽지가 않네요 이런 저런 원리도 적어 넣고 싶지만ㅠㅠ

    부족하지만 이 글을 읽고 이런 문제에 직면하신분들이 조금이나마 도움이 됐으면 합니다.

    반응형

    댓글

Designed by Tistory.