Java Spring数据JPA随时间大容量插入

Java Spring数据JPA随时间大容量插入,java,spring,spring-boot,spring-data-jpa,timertask,Java,Spring,Spring Boot,Spring Data Jpa,Timertask,我想用spring数据jpa将我的记录批量插入到oracle表中。我创建了一个列表,并在运行时将项目添加到列表中。列表大小为50,如果列表达到此大小,则将所有列表记录保存到数据库中,如果列表无法在100毫秒内达到完整大小,则清除列表,并将所有列表记录保存到数据库中。我用下面的测试类模拟了这种方式 @RunWith(SpringRunner.class) @Slf4j public class BulkInsertTest { static List<FraudRequestTra

我想用spring数据jpa将我的记录批量插入到oracle表中。我创建了一个列表,并在运行时将项目添加到列表中。列表大小为50,如果列表达到此大小,则将所有列表记录保存到数据库中,如果列表无法在100毫秒内达到完整大小,则清除列表,并将所有列表记录保存到数据库中。我用下面的测试类模拟了这种方式

@RunWith(SpringRunner.class)
@Slf4j
public class BulkInsertTest {

    static List<FraudRequestTransactionsEntity> requestTransactionsEntityList = new ArrayList<>(50);

    private Timer dbWriterTimer = new Timer("DBWriterTimer");

    @Mock
    FraudRequestTransactionsRepository fraudRequestTransactionsRepository;

    @Test
    public synchronized void saveRequestToDatabase(FraudActionsRestRequest fraudActionsRestRequest) {
        try {
            long start = System.currentTimeMillis();
            FraudRequestTransactionsEntity fraudRequestTransactionsEntity = new FraudRequestTransactionsEntity();

            if (requestTransactionsEntityList.size() != 10) {
                if(requestTransactionsEntityList.size()==0) {
                    CustomRequestTimerTask customTimerTask = new CustomRequestTimerTask(requestTransactionsEntityList);
                    dbWriterTimer.schedule(customTimerTask, 1000L, 1000L);
                }
                requestTransactionsEntityList.add(fraudRequestTransactionsEntity);
            } else {
                dbWriterTimer.cancel();
                fraudRequestTransactionsRepository.saveAll(requestTransactionsEntityList);
                log.info("REQ DB writing time reached list size: {} delta: {}", requestTransactionsEntityList.size(), System.currentTimeMillis() - start);
                requestTransactionsEntityList.clear();
            }

        } catch (Exception e) {
            log.error("[{}] Exception occured while FraudActionsRestRequest saving to db ", fraudActionsRestRequest.getTransactionId(), e);
        }
    }

    class CustomRequestTimerTask extends TimerTask {

        List<FraudRequestTransactionsEntity> fraudRequestTransactionsEntityList;

        CustomRequestTimerTask(List<FraudRequestTransactionsEntity> fraudRequestTransactionsEntityList) {
            this.fraudRequestTransactionsEntityList = fraudRequestTransactionsEntityList;
        }

        @Override
        public void run() {
            if(fraudRequestTransactionsEntityList.size()>0) {
                long start = System.currentTimeMillis();
                log.info("CustomRequestTimerTask executing with list size: {} ",fraudRequestTransactionsEntityList.size());
                fraudRequestTransactionsRepository.saveAll(fraudRequestTransactionsEntityList);
                fraudRequestTransactionsEntityList.clear();
                log.info("CustomRequestTimerTask REQ DB writing time reached timer time {}", System.currentTimeMillis() - start);
            }
        }
    }

}
@RunWith(SpringRunner.class)
@Slf4j
公共类BulkInsertTest{
静态列表请求TransactionEntityList=新的ArrayList(50);
专用计时器dbWriterTimer=新计时器(“dbWriterTimer”);
@嘲弄
FraudRequestTransactionRepository FraudRequestTransactionRepository;
@试验
公共同步的void saveRequestToDatabase(FraudActionsRestRequest FraudActionsRestRequest){
试一试{
长启动=System.currentTimeMillis();
FraudRequestTransactionEntity FraudRequestTransactionEntity=新的FraudRequestTransactionEntity();
if(requestTransactionEntityList.size()!=10){
if(requestTransactionEntityList.size()==0){
CustomRequestTimerTask customTimerTask=新的CustomRequestTimerTask(RequestTransactionEntityList);
dbWriterTimer.schedule(customTimerTask,1000L,1000L);
}
RequestTransactionEntityList.add(FraudRequestTransactionEntity);
}否则{
dbwriter.cancel();
FraudRequestTransactionRepository.saveAll(RequestTransactionEntityList);
log.info(“REQ DB写入时间已达到列表大小:{}增量:{}”,RequestTransactionEntityList.size(),System.currentTimeMillis()-start);
RequestTransactionEntityList.clear();
}
}捕获(例外e){
log.error(“[{}]在FraudActionsRestRequest保存到db时发生异常”,FraudActionsRestRequest.getTransactionId(),e);
}
}
类CustomRequestTimerTask扩展了TimerTask{
列出FraudRequestTransactionEntityList;
CustomRequestTimerTask(列表FraudRequestTransactionEntityList){
this.FraudRequestTransactionEntityList=FraudRequestTransactionEntityList;
}
@凌驾
公开募捐{
如果(FraudRequestTransactionEntityList.size()>0){
长启动=System.currentTimeMillis();
log.info(“使用列表大小执行的CustomRequestTimerTask:{}”,FraudRequestTransactionEntityList.size());
FraudRequestTransactionRepository.saveAll(FraudRequestTransactionEntityList);
FraudRequestTransactionEntityList.clear();
log.info(“CustomRequestTimerTask REQ DB写入时间已达到计时器时间{}”,System.currentTimeMillis()-start);
}
}
}
}

这是解决我问题的最佳方法吗?多线程是否存在任何线程安全问题

为什么不使用spring batch进行批量插入我正在使用,创建了一个列表和jparepository的saveAll方法已根据下面的文章批量插入了它们?那么您遇到了什么样的问题?我不知道如何在没有完整列表的情况下随时间保留记录