Quelle est la méthode recommandée pour réinitialiser une connexion gérée C3P0 à son état initial? J'utilise le pilote Microsoft JDBC et le SET ROWCOUNT 1
sur une connexion. Cela entraîne que toutes les requêtes exécutées par cette connexion ne renvoient qu'une seule ligne même après que la connexion a été renvoyée au pool et qu'elle a été récupérée plus tard. Dois-je réinitialiser les valeurs explicitement onCheckin
ou onCheckout
?Réinitialisation d'un état de connexion JDBC (c3p0)
Classe principale
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 - Principalement pour voir la connexion utilisée.
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 + "]");
}
}
Sans la ligne SET ROWCOUNT 1
, plusieurs lignes sont renvoyées par les requêtes ci-dessus. La journalisation du personnaliseur indique que la même connexion est utilisée.
Ne serait-il pas préférable de réinitialiser la valeur onCheckIn plutôt que onCheckOut? Je comprends des docs de c3p0 que Checkin est manipulé de façon asynchrone tandis que le contrôle est synchrone dans la nature. – calvinkrishy
@calvinkrishy - Bon point. J'ai mis à jour ma réponse. –