首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java中的多爬虫数据库连接

Java中的多爬虫数据库连接
EN

Stack Overflow用户
提问于 2015-05-04 03:27:42
回答 1查看 227关注 0票数 1

假设我为同一个URL实例化了多个爬虫。它们将URL写入MySQL数据库进行处理。在处理URL之前,它们会检查数据库中是否存在该页面的记录,这样就不会再次处理已经处理过的页面。

问题是,应该存在某种类型的锁,这样,如果我的逻辑是正确的,那么它们中只有一个可以从特定的表中读取或写入。因此,我只实例化了一个数据库连接(JDBC)供它们使用。尽管如此,我仍然不确定这是不是正确的做法。

所以我的问题是:从单个数据库连接执行的语句是按顺序运行的(它们是排队的)还是取决于数据库引擎的配置。

EN

回答 1

Stack Overflow用户

发布于 2015-05-06 16:34:47

因此,我只实例化了一个数据库连接(

)供它们使用。尽管如此,我仍然不确定这是不是正确的做法。

我最近遇到了一些类似的情况。我选择只有一个JDBC连接,并使用Lock在线程之间共享这个连接。

需要某种状态标志来指示一个特定的URL正在被处理。

查看我下面的简单代码片段,它说明了前面的几点。

从单个数据库连接执行的

do语句是按顺序运行(它们是排队的)还是取决于数据库引擎的配置。

要消除任何疑虑,请让您的Java代码确保语句按顺序运行。这将消除任何来自意外错误的后遗症。

代码片段

CrawlerThread.java

代码语言:javascript
复制
public class CrawlerThread extends Thread {

     public void run() {
         String url=null;
         try {
            String url = urlDao.getNextUrlToProcess();

            if (url!=null) {
                // Process URL here...
            }
         } catch(Exception e) {
              // Handle exception here...
         } finally {
            urlDao.markUrlAsFetched(url);
         }
     }
}

UrlDAO.java

代码语言:javascript
复制
public class UrlDAO {

      public String getNextUrlToProcess() {
          Connection jdbcConnection = null;
          String url = null;

          try {
              jdbcConnection = connectionManager.acquireSharedConnection();

              // Perform query to get next url
              // SELECT url FROM urls WHERE status = 'NEED_FETCH' LIMIT 1
              ResultSet rs = ...
              if (rs.next()) {
                  url = ...

                  // Mark url as being processed
                  setUrlStatus(jdbcConnection, url, 'BEING_FETCHED');
              }
          } catch(Exception e) {
              // Handle exception here...
          } finally {
              connectionManager.releaseSharedConnection();
          }

          return url;
      }

      public void markUrlAsFetched(String url) {
          Connection jdbcConnection=null;

          try {
              jdbcConnection = connectionManager.acquireSharedConnection();

              setUrlStatus(jdbcConnection, url, 'FETCHED');
          } catch(Exception e) {
              // Handle exception here...
          } finally {
              connectionManager.releaseSharedConnection();
          }
      }

      private void setUrlStatus(Connection jdbcConnection, String url, String newStatus) {
          // UPDATE urls SET status = ? WHERE url = ?
          if (url!=null) {
             ...
          }
      }
}

ConnectionManager.java

代码语言:javascript
复制
/**
 *
 * The ConnectionManager opens, closes and shares a JDBC connection among the different threads.
 *
 */
public class ConnectionManager {
     private Lock connectionLock = new ReentrantLock();
     private Connection sharedConnection = ... 

     public Connection acquireSharedConnection() {
          connectionLock.lock();
          return sharedConnection;
     }

     public void releaseSharedConnection() {
          connectionLock.unlock();
     }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30018389

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档