В приложении с весенней загрузкой у меня есть несколько реализаций интерфейса, каждая из которых обращается к базе данных с помощью репозитория JPA.
@Autowired
List<? extends CrawlerService> crawlers;
Это хранилище:
@Repository
public interface HotelRepository extends JpaRepository<Hotel, Long> {
public Optional<Hotel> findByTextAndSource(String text, String source);
}
И реализации выглядят так:
@Service
public class MyService implements CrawlerService {
@Autowired
DocumentService documentService;
@Autowired
HotelRepository hotelRepository;
private Logger logger = LoggerFactory.getLogger("MyService");
private Set<String> visitedLinks = new HashSet<>();
@Override
public void start() {
execute("https://www.example.com/");
}
public void execute(String url) {
if(visitedLinks.contains(url))
return;
try {
logger.info("Connecting '{}' ...", url);
visitedLinks.add(url);
Document document = Jsoup.connect(url).get();
String text = documentService.getText(document);
// this is where I access to the database
if(hotelRepository.findByTextAndSource(text, "EXAMPLE").isPresent()) {
return;
}
Hotel hotel = new Hotel();
hotel.setUrl(url);
hotel.setText(text);
hotel.setSource("EXAMPLE");
hotelRepository.save(hotel);
// find other links
findLinks(document, url).forEach(this::execute);
} catch (IOException e) {
logger.error("Connection error for {}", url);
}
}
}
Теперь я использую параллельный поток для параллельного запуска каждого из них:
crawlers.stream().parallel().forEach(CrawlerService::start);
Они продолжают работать до тех пор, пока не захотят получить доступ к базе данных через репозиторий JPA. Затем все они останавливаются, кроме одного, назначенного основному потоку. Это наблюдается с помощью вывода моего логгера:
2018-11-01 21:42:38.408 INFO 7641 --- [ main] MyService ...
Только этот продолжает работать.
Я хочу, чтобы все они продолжали работать параллельно. Как я могу решить эту проблему?
Стоит отметить, что я использую MySQL и Spring Boot 2 с настройками по умолчанию для пула соединений.