2017-05-16 15 views
0

私はJsoupに基づいてパーサを作った。このパーサは、ページ番号付きのページを処理します。このページには、たとえば、解析される100のリンクが含まれています。私は改ページを行うメインループを作成しました。そして、私は非同期タスクを実行して、各ページの100項目を解析する必要があります。私が理解するように、Jsoupは非同期要求処理をサポートしていません。各アイテムを処理した後、DBに保存する必要があります。 DBのテーブルに挿入中にエラーが発生しないようにしたいと考えています(可能であれば、スレッドは異なるアイテムに対して同じIDを同時に使用します)。あなたは何を提案できますか?DBへの同時挿入

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()); 
     } 
    } 
} 

私はこのコードはコンパイル可能ではないことを知っている、私はあなたに私の考えを示したいと思います。

または、バネバッチを使用する方がよいでしょうか? これを解決するベストプラクティスは何ですか? あなたはどう思いますか?

+0

トランザクションを使用すると、挿入中にエラーを回避し、トランザクションを使用すると挿入が非常に高速になります。 –

+0

@utsavanandとはどのような分離レベルですか? –

答えて

2

行レベルのロックを使用する場合は問題ありません。これは、各インサートをトランザクションにするために問題を節約するかもしれませんが、これはトランザクションの全体概念が作業単位として与えられていることを意味します(つまり、1つのインサートが失敗した場合、

また、UUIDまたはdb生成IDを使用すると、衝突の問題は発生しません。

コードの構造については、各タスクのRunnablesとスレッドプールエグゼキュータを参照してください。スレッドが多すぎると、システム全体を管理しようとすると効率が低下します。 https://docs.spring.io/spring/docs/current/spring-framework-reference/html/scheduling.html

+0

ですから、JPAリポジトリを使用してDBを保存することは可能です(ただし、行レベルのロックを使用するにはこのリポジトリを設定する前に)? –

+0

明らかに、行レベルのロックは、SQLデータベースの概念です。他のストレージ技術にはアナログがありますが、SQL DBの場合はデータベースで設定するものです。たとえば、mysql:https://dev.mysql.com/doc/refman/5.7/en/internal-locking.html – Taylor

関連する問題