【问题标题】:COPY FROM and C3PO connection pool in PostgresPostgres中的COPY FROM和C3PO连接池
【发布时间】:2013-01-10 11:30:08
【问题描述】:

我的 JAVA 程序中有以下代码,允许我将文件中的数据复制到我的 Postgres 数据库中:

Connection con = DriverManager.getConnection("jdbc:postgresql://localhost:####/myDb", 
                                                   "myuser", "mypassword"); 
CopyManager cm = new CopyManager((BaseConnection) con);
cm.copyIn("COPY prices FROM STDIN WITH DELIMITER AS ','", 
             new BufferedReader(new FileReader(filepath)), buffersize);

这段代码运行良好,但我想使用连接池来管理我的连接,因为我有很多文件运行这段代码。所以我使用了C3P0

public static final ComboPooledDataSource cpds = new ComboPooledDataSource();

public class MyPooledConnection {
MyPooledConnection() throws PropertyVetoException {
    cpds.setDriverClass("org.postgresql.Driver"); 
    cpds.setJdbcUrl("jdbc:postgresql://localhost:5432/myStockDatabase"); 
    cpds.setUser("myUserName"); 
    cpds.setPassword("myPassword"); 
    cpds.setInitialPoolSize(4);
    cpds.setMinPoolSize(4);
    cpds.setMaxIdleTime(30);
    cpds.setMaxPoolSize(MAX_CONNECTIONS);
}

public static Connection getConnection() {
    return cpds.getConnection();
}
}

但是,当我从上面的连接池中获取连接并尝试将其与 CopyManager 一起使用时,如下例所示,代码不起作用

Connection pooled_con = MyPooledConnection.getConnection();
CopyManager cm = new CopyManager((BaseConnection) pooled_con);
cm.copyIn("COPY prices FROM STDIN WITH DELIMITER AS ','", 
             new BufferedReader(new FileReader(filepath)), buffersize);

我猜问题出在连接上,但我似乎无法弄清楚它有什么不同。我试过用 SQLException 和 IOException 来捕捉错误,但它也没有捕捉到。有人遇到过吗?

----更新----

感谢 a_horse_with_no_name 对此的指导。以下代码对我有用

// Cast the connection as a proxy connection
C3P0ProxyConnection proxycon = (C3P0ProxyConnection)cpds.getConnection();
try {

    // Pass the getCopyAPI (from PGConnection) to a method
    Method m = PGConnection.class.getMethod("getCopyAPI", new Class[]{});
    Object[] arg = new Object[] {};

    // Call rawConnectionOperation, passing the method, the raw_connection, 
    // and method parameters, and then cast as CopyManager
    CopyManager cm = (CopyManager) proxycon.rawConnectionOperation(m,
                                         C3P0ProxyConnection.RAW_CONNECTION,arg);
    cm.copyIn("COPY prices FROM STDIN WITH DELIMITER AS ','", new BufferedReader(new 
                                                FileReader(filepath)), buffersize);
} catch (NoSuchMethodException | IllegalAccessException 
                        | IllegalArgumentException | InvocationTargetException e) {
    // Deal with errors here
}

【问题讨论】:

  • 错误的完整堆栈跟踪是?为什么要从构造函数初始化静态字段?是什么让您认为 C3P0 返回的连接是 BaseConnection 的实例(无论这个类可能是什么?)
  • 不起作用是什么意思?是否抛出任何类型的异常?挂了吗?
  • @AHungerArtist:“不起作用”,因为文件中的数据不会复制到表中。没有抛出异常,也没有挂起;它就像代码被执行一样继续。
  • @JB Nizet:没有抛出堆栈跟踪,我从构造函数初始化了它,所以我只有一个池实例,而且我知道 C3P0 不返回 BaseConnection 的实例;这就是我试图投射它的原因?这是我的错误吗?
  • 我不知道。在调试器中执行代码以查看它的作用。我们对您的代码知之甚少。我怀疑你正在捕捉抛出的异常。此外,只有当对象是此类的实例时,才能将对象强制转换为类。

标签: java postgresql jdbc c3p0


【解决方案1】:

池不给你“本机”连接,它总是分发一个代理对象:

来自手册:

C3P0 将这些对象包装在代理后面,因此您不能将 C3P0 返回的连接或语句转换为特定于供应商的实现类

您可能无法通过 C3P0 使用 CopyManager。我不确定,但也许您可以使用此处描述的解决方法:http://www.mchange.com/projects/c3p0/#raw_connection_ops

如果这不起作用,您可能需要使用不同的连接池(例如新的Tomcat 7 JDBC-Pool),让您可以访问底层本机连接。

【讨论】:

  • 感谢您为我指明正确的方向。原始连接是我让它工作所需要的。我将使用我使用的代码更新我的原始帖子,使其工作。
【解决方案2】:
CopyManager cm = new CopyManager(cpds.getConnection().unwrap(PgConnection.class))

为我工作。

【讨论】:

    猜你喜欢
    • 2014-08-06
    • 2014-07-07
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 2021-10-05
    • 2017-10-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多