hsqldb 데이터베이스에 파일을 저장하려고하는 간단한 Java 코드를 작성했습니다. 모든 작업은 특정 디렉토리의 파일을 읽고 DB에 저장하는 것입니다. 그것은 단일 스레드이지만 나중에 다중 스레드 액세스에 대처할 수 있도록하기 위해 아파치 commons.dbcp에서 풀링 된 연결을 사용하고 있습니다.commons.dbcp에서 풀링 된 연결을 사용하여 다음과 같은 간단한 Java 코드가 차단되는 이유는 무엇입니까?
문제는 코드가 몇 개의 파일을 읽은 후에 차단된다는 것입니다.
전체 소스 코드를 아래에서 찾으십시오.
는 Program.java
import java.io.File;
import java.io.IOException;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.apache.commons.dbcp.ConnectionFactory;
import org.apache.commons.dbcp.DriverManagerConnectionFactory;
import org.apache.commons.dbcp.PoolableConnectionFactory;
import org.apache.commons.dbcp.PoolingDataSource;
import org.apache.commons.pool.KeyedObjectPoolFactory;
import org.apache.commons.pool.impl.GenericKeyedObjectPoolFactory;
import org.apache.commons.pool.impl.GenericObjectPool;
public class Program {
public static DataSource getPoolingDataSource(String driverClass, String url, String user, String password) throws ClassNotFoundException {
Class.forName(driverClass);
ConnectionFactory connectionFactory = new DriverManagerConnectionFactory(url, user, password);
GenericObjectPool connectionPool = new GenericObjectPool();
KeyedObjectPoolFactory stmtPool = new GenericKeyedObjectPoolFactory(null);
new PoolableConnectionFactory(connectionFactory, connectionPool, stmtPool, null, false, true);
return new PoolingDataSource(connectionPool);
}
public static void main(String[] args) throws ClassNotFoundException, SQLException, IOException, InterruptedException {
String root = args.length == 0 ? "c:/Work/java/ntxdb" : args[0];
Runtime run = Runtime.getRuntime();
Process pr = run.exec("cmd /c del /s/q c:\\tmp\\file.db*");
pr.waitFor();
DataSource ds = getPoolingDataSource("org.hsqldb.jdbcDriver", "jdbc:hsqldb:file:c:/tmp/file.db", "sa", "");
HsqldbFileStorage fs = new HsqldbFileStorage(ds);
putFiles(fs, new File(root));
}
private static void putFiles(HsqldbFileStorage fs, File parent) throws IOException, SQLException {
for (File child : parent.listFiles()) {
if (child.isDirectory()) {
putFiles(fs, child);
} else {
System.out.println(child.getCanonicalPath());
fs.put(child);
}
}
}
}
HsqldbFileStorage.java
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import javax.sql.DataSource;
public class HsqldbFileStorage {
private static final String SET_SQL = "MERGE INTO test" +
" USING (VALUES ?, CAST(? AS BLOB)) I (name, data)" +
" ON (test.name=I.name)" +
" WHEN MATCHED THEN UPDATE SET test.data = I.data" +
" WHEN NOT MATCHED THEN INSERT (name, data) VALUES (I.name, I.data)";
private DataSource m_dataSource;
public HsqldbFileStorage(DataSource dataSource) throws SQLException {
super();
m_dataSource = dataSource;
Connection c = dataSource.getConnection();
c.createStatement().execute("Create Cached Table IF NOT EXISTS test (name VARCHAR(256), data BLOB(10M));");
}
public void put(File file) throws IOException, SQLException {
put(file.getCanonicalPath(), file);
}
public void put(String name, File file) throws IOException, SQLException {
InputStream is = new BufferedInputStream(new FileInputStream(file));
try {
put(name, is);
} finally {
is.close();
}
}
public void put(String name, InputStream data) throws SQLException, IOException {
PreparedStatement set = m_dataSource.getConnection().prepareStatement(SET_SQL);
try {
set.setString(1, name);
set.setBinaryStream(2, data);
set.executeUpdate();
} finally {
set.close();
}
}
}
코드에 따라 평민 - DBCP 1.6 HSQLDB 2.2.9
공유지 풀, 1.4 그것을 프로젝트 디렉토리 자체에서 실행하면 62 개의 파일을 DB에 저장해야합니다. 위에서 언급 한 두 가지 소스 파일보다 파일이 더 낫다.), 각 파일에 대한 줄을 출력한다.
불행하게도, 그것은 다음과 같은 스택 추적과 여덟 번째 파일에 블록 :
at java.lang.Object.wait(Object.java:-1)
at java.lang.Object.wait(Object.java:485)
at org.apache.commons.pool.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:1118)
at org.apache.commons.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:106)
at HsqldbFileStorage.put(HsqldbFileStorage.java:41)
at HsqldbFileStorage.put(HsqldbFileStorage.java:34)
at HsqldbFileStorage.put(HsqldbFileStorage.java:28)
at Program.putFiles(Program.java:42)
at Program.putFiles(Program.java:39)
at Program.putFiles(Program.java:39)
at Program.main(Program.java:33)
내가 잘못 뭐하는 거지?
나는 바보 야. 고맙습니다. – mark