2016-12-22 2 views
0

Я хочу, чтобы улучшить производительность кода здесь, у меня есть это работает:Как спросить JPA о накоплении транзакций?

List<Doctor> team = doctorService.getAll(); team.stream() .filter(doctor -> !doctor.equals(msg.getSender())) .forEach(doctor -> { ChatMessageTeam chatMsg = new ChatMessageTeam(); chatMsg.setDoctor(doctor); chatMsg.setMessage(msg); rep.save(chatMsg); });

rep является JPA хранилище собственной сборки.

И я хочу параллелировать этот поток, но когда я поместил .parallel в поток, у меня появилась ошибка, как я увидел, потому что диспетчер объектов не подготовлен к этому. Поэтому я думаю (и не выяснил, как), что я могу сделать, это аккумулировать транзакции и объединить все их вместе в одном запросе. Другие предложения приветствуются.

Спасибо за ваше время, читая это!

+0

Является ли 'rep' самодельным хранилищем? Используете ли вы какую-либо фреймворк/библиотеку, помогающую вам с вашей настойчивостью? В зависимости от этого вы можете объявить одну транзакцию, в которой вы будете выполнять свои сейвы. – oschlueter

+0

Да, это репозиторий для самостоятельной сборки, я добавлю это в вопрос. И библиотекой, которую я использую, является JPA. –

ответ

0

Чтобы продемонстрировать подход к выполнению нескольких инструкций базы данных в одной транзакции, я завернул ваш код в метод, а затем добавил аннотацию @Transactional к этому методу. Таким образом, ваш метод будет либо обрабатываться в существующей транзакции, либо будет создана транзакция для вас. Если это не работает в вашей среде, укажите сообщения об ошибках или трассировки стека.

import javax.transaction.Transactional; 

// ... 

@Transactional 
public void store() { 
    List<Doctor> team = doctorService.getAll(); 
    team.stream() 
      .filter(doctor -> !doctor.equals(msg.getSender())) 
      .forEach(doctor -> { 
       ChatMessageTeam chatMsg = new ChatMessageTeam(); 
       chatMsg.setDoctor(doctor); 
       chatMsg.setMessage(msg); 
       rep.save(chatMsg); 
      }); 
} 
+0

Он работает нормально, но я все еще не могу параллелировать поток, не улучшил производительность ... –

0

Я думаю, что в вашем потребительной случае .parallel медленнее. Но вы можете обернуть все в один метод в свое репо для одного коммита.

List<Doctor> team = doctorService.getAll(); 
    List<ChatMessageTeam> cmtList = team.stream() 
     .filter(doctor -> !doctor.equals(msg.getSender())) 
     .map(doctor -> new ChatMessageTeam(doctor ,msg)) 
     .collector(Collectors.toList())); 
    rep.saveList(cmtList); 


@Transactional 
public saveList(List<ChatMessageTeam> list){ 
    for(ChatMessageTeam ctm: list){ 
     save(ctm); 
    } 
} 
+0

Почему вы говорите, что это будет медленнее? и ваше решение не будет запускать список дважды? один в команде 'for', а другой - в' stream'? –

+0

Накладные расходы от fork-join выше, чем продолжительность исполнения. http://stackoverflow.com/questions/20375176/should-i-always-use-a-parallel-stream-when-possible saveList - это метод из вашего репо. Я бы разделил сборку и спасение. – jklee

Смежные вопросы