假设我为同一个URL实例化了多个抓取工具。他们编写处理到MySQL数据库的URL。在处理URL之前,如果该页面的记录存在,它们会检入数据库,因此它不会再次处理已处理的页面。
这是catch,应该存在某种锁,因此如果我的逻辑是正确的,那么只有其中一个可以从该特定表中读取或写入。因此,我只实例化了一个数据库连接(JDBC)供他们使用。不过,我不确定这是否正确。
所以我的问题是:从单个数据库连接执行的语句是按顺序运行的(它们是否排队),还是依赖于数据库引擎的配置。
答案 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();
}
}