Java Spring数据JPA随时间大容量插入
我想用spring数据jpa将我的记录批量插入到oracle表中。我创建了一个列表,并在运行时将项目添加到列表中。列表大小为50,如果列表达到此大小,则将所有列表记录保存到数据库中,如果列表无法在100毫秒内达到完整大小,则清除列表,并将所有列表记录保存到数据库中。我用下面的测试类模拟了这种方式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
@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方法已根据下面的文章批量插入了它们?那么您遇到了什么样的问题?我不知道如何在没有完整列表的情况下随时间保留记录