繁体   English   中英

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

[英]multiple threads using same value fetched by database DAO class method

Status: solved

我必须制作一个pastebin,因为我必须指出行号。

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

相关链接:

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

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

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

line 252

and line 223

该链接标记为已processed. (true) processed. (true)在db中。 crawler class其他线程也可以。 所以当line 252应该得到一个链接。 它应该被processed = false 但我看到所有threads take same link.

当其中一个线程抓取链接时。 它使得它被处理=真。 其他人则不应抓它。 (得到它)是标记的processed = true。


getNonProcessedLinkFromDB()返回未处理的链接

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

getNonProcessedLinkFromDB将查看处理过的= false链接并给出其中一个。 limit 1 每个线程的起始间隔间隔为20秒。
在一个线程内。 1或2秒(估计爬行的处理时间)

line 98  keepS threads from grabbing the same url

如果你看到结果。 一个线程使它成为现实。 还有其他人访问它。 waaaay过了一段时间。

所有线程都是分开的。 甚至一场races db在第一个线程处理它时使链接成立

这是一个没有提出简明问题的情况。 那里有很多代码, 不知道发生了什么。 你需要将它分解,以便你能够理解它出错的地方,然后告诉我们这一点。

有些潜在冲突的事情。

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

我没有阅读日志,因为它们对我没用。

-edit for comment-数据库通常有交易。 在提交之前,您在一个事务中进行的修改在其他事务中不会出现。 交易可以回滚。 您需要查看获取刚更新的行并查看值是否真的发生了变化。 在另一个事务或另一个连接中执行此操作。

20秒的间隙看起来只有在过程开始时才会出现。 想象一个线程1处理URL1线程处理URL2的情况。 他们都在大约同一时间完成。 它们都寻找下一个未处理的URL(比如URL3 )。 他们都会开始处理这个Url,因为他们不知道另一个线程已启动它。 您需要一个流程来分发Url,可能是您想要查看的队列。

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

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

在crawl()方法体的开头。

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

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

    crawl(nonProcessedLinkFromDB);

实际上解决了这个问题

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

Synchonized block有助于进一步发展。

感谢帮助。 IRC频道上的“Fuber”。 Quakenet服务器#java和Freenode服务器## javaee

和所有支持我的人!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM