【问题标题】:Resetting a JDBC connection state (c3p0)重置 JDBC 连接状态 (c3p0)
【发布时间】:2018-02-25 09:28:39
【问题描述】:

将 C3P0 托管连接重置为其初始状态的推荐方法是什么?

我正在使用 Microsoft JDBC 驱动程序并在一个连接上设置SET ROWCOUNT 1。这会导致该连接执行的所有查询仅返回一行即使在连接已返回到池并随后再次获取之后。我应该明确重置值onCheckin 还是onCheckout

主类

    import com.mchange.v2.c3p0.ComboPooledDataSource;
    import java.beans.PropertyVetoException;
    import java.sql.SQLException;
    import java.sql.Statement;
    
    import java.sql.Connection; 
    import java.sql.ResultSet;
    
    public class Main {
    
        final ComboPooledDataSource cpds;
        
        Main() throws PropertyVetoException {
            cpds = new ComboPooledDataSource();
            cpds.setDriverClass("com.microsoft.sqlserver.jdbc.SQLServerDriver");
            cpds.setJdbcUrl("jdbc:sqlserver://10.42.62.41:1433;databaseName=mach;integratedSecurity=false;SendStringParametersAsUnicode=true;applicationName=panda;");
            cpds.setUser("testuser");
            cpds.setPassword("welcome123");
            cpds.setInitialPoolSize(0);
            cpds.setMinPoolSize(1);
            cpds.setMaxPoolSize(1);
            cpds.setConnectionCustomizerClassName("C3p0ConnectionCustomizer");
            cpds.setDescription("Netbeans test project");
        }
        
        Connection getConnection() throws SQLException{
            return cpds.getConnection();
        }
        
        public static void main(String[] args) throws PropertyVetoException, SQLException {
            Main m = new Main();
            
            try(Connection connection = m.getConnection()){
                Statement stmt = connection.createStatement();
                stmt.execute("SET ROWCOUNT 1");
            }
            
            try(Connection connection = m.getConnection()){
                try(Statement stmt = connection.createStatement()) {
                    int cnt = 0, rsCnt = 0;
                    boolean results = stmt.execute("select * from Foo; select * from Bar");
                    if(results) {
                        do {
                            rsCnt++;
                            ResultSet rs = stmt.getResultSet();
                            while(rs.next()) {
                                cnt++;
                            }
                            System.out.println(rsCnt + " -> " + cnt);
                            rs.close();
                            results = stmt.getMoreResults();
                            cnt = 0;
                        } while (results);
                    }
                }
            }
            
        }
    
    }

Customizer - 主要是查看正在使用的连接。

    import com.mchange.v2.c3p0.AbstractConnectionCustomizer;
    import java.sql.Connection;
    import java.sql.SQLException;
    import java.sql.Statement;
    
    public class C3p0ConnectionCustomizer extends AbstractConnectionCustomizer {
    
        @Override
        public void onAcquire(Connection c, String pdsIdt) {
            try (Statement stmt = c.createStatement()) {
                stmt.execute("SET ROWCOUNT 0");
            } catch(SQLException sqle) {
                sqle.printStackTrace();
            }
        }
    
        @Override
        public void onCheckOut(Connection c, String pdsIdt) {
            System.out.println("Checked out " + c + " [" + pdsIdt + "]");
        }
    
        @Override
        public void onCheckIn(Connection c, String pdsIdt) throws SQLException {
            System.out.println("Checking in " + c + " [" + pdsIdt + "]");
    
        }
    
    }

如果没有SET ROWCOUNT 1 行,上述查询会返回更多行。定制器日志显示正在使用相同的连接。

【问题讨论】:

    标签: sql-server jdbc c3p0


    【解决方案1】:

    有人可能会争辩说,理想情况下,调用SET ROWCOUNT 1 的代码确实应该“自行清理”,方法是确保在将连接释放回池之前调用SET ROWCOUNT 0

    但是,如果我们不能绝对保证这种行为,那么将您的 SET ROWCOUNT 0 调用从 onAcquire 方法转移到 onCheckIn 方法似乎是很合理的。即使重置ROWCOUNT 并不是真正必要的,但每次签到都会导致额外的往返行程,但SET ROWCOUNT 0 将是一个相对便宜的操作。

    (我刚刚用 c3p0-0.9.5.2 和 mssql-jdbc 试了一下,将SET ROWCOUNT 0 移到onCheckIn 方法中达到了预期的效果。)

    【讨论】:

    • 重置值onCheckIn而不是onCheckOut不是更好吗?我从 c3p0 文档中了解到,签入是异步处理的,而签出本质上是同步的。
    猜你喜欢
    • 2022-08-09
    • 2011-12-07
    • 2016-08-02
    • 2010-11-30
    • 1970-01-01
    • 2013-08-27
    • 1970-01-01
    • 2018-06-26
    • 2015-02-25
    相关资源
    最近更新 更多