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

时间:2015-05-03 19:27:42

标签: java mysql database jdbc

假设我为同一个URL实例化了多个抓取工具。他们编写处理到MySQL数据库的URL。在处理URL之前,如果该页面的记录存在,它们会检入数据库,因此它不会再次处理已处理的页面。

这是catch,应该存在某种锁,因此如果我的逻辑是正确的,那么只有其中一个可以从该特定表中读取或写入。因此,我只实例化了一个数据库连接(JDBC)供他们使用。不过,我不确定这是否正确。

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

1 个答案:

答案 0 :(得分:0)

  

因此,我只实例化了一个数据库连接(JDBC)供他们使用。不过,我不确定这是否正确。

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

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

检查下面的简单代码段,说明以前的观点。

  

从单个数据库连接执行的语句是按顺序运行的(它们是否排队),还是依赖于数据库引擎的配置。

为了消除任何疑问,让您的Java代码确保语句按顺序运行。这将消除以后出现意外错误的任何头条。

代码段

<强> CrawlerThread.java

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

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

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