多个线程使用数据库 DAO 类方法获取的相同值



Status: solved

我不得不做一个糊状物,因为我必须指出行号。

注意:不使用执行程序服务或线程池。 只是为了理解以这种方式启动和使用线程有什么问题。如果我使用 1 个线程。 该应用程序工作完美!

相关链接:

http://www.postgresql.org/docs/9.1/static/transaction-iso.htmlhttp://www.postgresql.org/docs/current/static/explicit-locking.html

main app, http://pastebin.com/i9rVyari logs、http://pastebin.com/2c4pU1K8、http://pastebin.com/2S3301gD

我在 for 循环中启动了许多线程 (10) 并实例化一个 runnable 类,但似乎我从 db 中得到了相同的结果(我从 db 获取了一些字符串,然后更改了它),但each thread, I get same string (尽管每个线程都改变了它。 使用jdbc进行postgresql 常见的问题是什么?

line 252
and line 223

该链接在数据库中标记为processed. (true)crawler class的其他线程也这样做。所以什么时候line 252应该得到一个链接。应该是processed = false. 但我看到了所有threads take same link.

当其中一个线程对链接进行爬网时。 它使其已处理 = true。 然后其他人不应该爬行它。(得到它)是它标记的已处理 = 真。

<小时 />

getNonProcessedLinkFromDB()返回未处理的链接

public String getNonProcessedLink(){        line 645
public boolean markLinkAsProcesed(String link){   line 705

getNonProcessedLinkFromDB将看到已处理的=虚假链接,并从中给出一个. limit 1每个线程的起始间隔为 20 秒。在一个线程内。 1 或 2 秒(估计抓取的处理时间)

line 98  keepS threads from grabbing the same url

如果你看到结果。 一个线程使它成为现实。 还有一些人访问它。 过了一会儿哇哇。

所有线程都是独立的。 甚至一个races. 数据库使链接在第一个线程处理它的那一刻为真

这是一个不是一个简洁的问题被问到的情况。里面有很多代码,不知道发生了什么。您需要将其分解,以便了解哪里出了问题,然后向我们展示这一点。

一些潜在冲突的事情。

  • 您正在为几乎每个进程打开数据库连接。应用程序的正常流程是打开几个连接,执行一些处理,然后关闭它们。
  • 您是否正在处理数据库提交?我不记得postres数据库的默认设置是什么,你必须研究一下。
  • 单个 URL 处于 3 种状态。未处理,正在处理,已处理。我认为您根本没有处理"正在处理"状态。由于处理需要时间并且可能会失败,因此您必须考虑这些情况。

我没有阅读日志,因为它们对我来说毫无用处。

-编辑评论-数据库通常具有事务。在一个事务中所做的修改在提交之前不会在其他事务中看到。事务可以回滚。您需要查看获取刚刚更新的行,并查看该值是否真的发生了更改。在另一个事务或其他连接上执行此操作。

20 秒的间隔看起来只有在进程启动时才存在。想象一下线程 1 处理 URL1线程 2 处理 URL2 的情况。它们几乎同时完成。它们都在寻找下一个未处理的URL(例如URL3)。他们都会开始处理这个 URL,因为他们不知道另一个线程已经启动了它。您需要一个进程来分发 URL,您可能要查看队列。

如果您知道哪些线程正在处理哪些 URL,则可能会改进日志记录。您还需要较小的样本量,以便了解正在发生的事情。

尽管这篇文章中助手的评论和回应也是正确的。

在 crawl() 方法主体的开头。

    synchronized(Crawler.class){
        url = getNonProcessedLinkFromDB();
        new BasicDAO().markLinkAsProcesed(url);
    }

在 crawl() 方法主体的底部(当它完成处理时):

    crawl(nonProcessedLinkFromDB);

实际上解决了问题。

这是将处理为true的链接标记为true和获取新链接之间的差距,并让其他线程在当前处理时获得相同的链接。

Synchonized block进一步帮助。

感谢帮手。IRC频道上的"Fuber"。Quakenet 服务器 #java 和 Freenode 服务器 ##javaee

以及所有支持我的人!

最新更新