gpt4 book ai didi

java - 并发插入数据库

转载 作者:行者123 更新时间:2023-12-02 02:50:02 25 4
gpt4 key购买 nike

我做了一个基于Jsoup的解析器。该解析器处理带有分页的页面。例如,该页面包含 100 个要解析的链接。我创建了一个主循环来进行分页。我需要运行异步任务来解析每个页面上的 100 个项目。据我了解,Jsoup 不支持异步请求处理。处理完每个项目后,我需要将其保存到数据库中。我想避免在插入数据库表期间出现错误(如果可能的话,线程将同时对不同项目使用相同的 id)。你有什么建议?我可以使用简单的 Thread 实例来解析每个项目吗:

public class ItemParser extends Thread {
private String url;
private MySpringDataJpaRepository repo;

public ItemParser(String url, MySpringDataJpaRepository repoReference) {
this.url = url;
this.repo = repoReference;
}

@Override
public void run() {
final MyItem item = jsoupParseItem();
repo.save(item);
}
}

然后运行如下:

public class Parser {

@Autowired
private MySpringDataJpaRepository repoReference; // <-- SINGLETON

public static void main(String[] args) {
int pages = 10000;
for (int i = 0; i < pages; i++) {
Document currentPage = Jsoup.parse();
List<String> links = currentPage.extractLinks(); // contains 100 links to be parsed on each for-loop iteration
links.forEach(link -> new ItemParser(link, repoReference).start());
}
}
}

我知道这段代码无法编译,我只是想向您展示我的想法。

或者也许使用 Spring Batch 更好?解决这个问题的最佳实践是什么?你觉得怎么样?

最佳答案

如果使用行级锁定应该没问题。让每个插入都是一个事务可能会解决问题,但是考虑到事务作为一个工作单元的整个概念,这会产生影响(即,如果单个插入失败,您是否希望整个运行失败并回滚?)。

此外,如果您使用 UUID 或数据库生成的 id,则不会出现任何冲突问题。

至于如何构建代码,我会考虑为每个任务使用 Runnables 以及线程池执行器。线程太多,系统会因尝试管理所有线程而失去效率。我注意到你正在使用 spring,所以看看 https://docs.spring.io/spring/docs/current/spring-framework-reference/html/scheduling.html

关于java - 并发插入数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44002334/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com