Java Forum / First Aid / November 2005
Issue managing multiple MySQL database connections
jjmbcom@gmail.com - 15 Nov 2005 19:23 GMT Hello folks,
Sorry if this is a basic question. I have an application that establishes a connection to two databases vua JDBC. Basically the application pulls data from database-a, processes it, then writes it to database-b. I have created by own DbClient class which basically abstracts some of the work associated with connecting to MySQL databases.
Prior to entering the main processing loop I create two separate instances of the my DbClient class, one to connect to database-a and another for database-b. Shortly after entering the main processing loop I call a method on the first instance of DbClient, supposedly connected to database-a. Oddly enough this connection is not in fact connected to database-a, instead it is connected to database-b. It almost seems that there is some LILO logic in the mix or the last DbClient instance is simply overwriting the first?
Any advice would be greatly appreciated.
John
"." - 15 Nov 2005 19:42 GMT > Hello folks, > [quoted text clipped - 15 lines] > > Any advice would be greatly appreciated. Hard to say without seeing the code. Could you be sharing an instance variable? Could you be using a class variable? I would guess if it is something like a shared variable, it would be in the DbClient class you created.
 Signature Send e-mail to: darrell dot grainger at utoronto dot ca
jjmbcom@gmail.com - 15 Nov 2005 21:05 GMT Source code for the DbClient class is below:
/* * DbClient.java * * Created on November 9, 2005, 4:44 PM * * To change this template, choose Tools | Options and locate the template under * the Source Creation and Management node. Right-click the template and choose * Open. You can then make changes to the template in the Source Editor. */
package xyz;
import org.apache.log4j.Logger; import org.apache.log4j.BasicConfigurator; import org.apache.log4j.PropertyConfigurator;
import java.sql.*; import java.sql.DriverManager; import java.util.*;
/** * * @author jbrzozowski */ public class DbClient { private static final String CLASSNAME = DbClient.class.getName(); public static Logger logger = Logger.getLogger(CLASSNAME);
private static final String D_DBURL = null; private static Connection connection = null; private static String driverName = "com.mysql.jdbc.Driver"; private static final String D_DBTYPE = "mysql"; private static final String D_DBHOST = "localhost"; private static final String D_DBUSER = "test"; private static final String D_DBPASS = "test"; private static final String D_DBNAME = "test";
private static String dbUrl = D_DBURL; private static String dbHost = D_DBHOST; private static String dbUser = D_DBUSER; private static String dbPass = D_DBPASS; private static String dbName = D_DBNAME; private static String dbType = D_DBTYPE;
/** * Creates a new instance of DbClient */ public DbClient() { }
public DbClient(String type, String host, String user, String pass, String name) { if(type != null) { dbType = type; } if(host != null) { dbHost = host; } if(user != null) { dbUser = user; } if(pass != null) { dbPass = pass; }
dbUrl = "jdbc:mysql://" + dbHost + "/" + dbName; }
public static void dump() { logger.debug("Database Host = " + dbHost); logger.debug("Database Type = " + dbType); logger.debug("Database Name = " + dbName); logger.debug("Database User = " + dbUser); logger.debug("Database Pass = " + dbPass); }
public boolean connect() throws Exception { boolean connected = false; this.dump(); try { // Load the JDBC driver driverName = "com.mysql.jdbc.Driver"; // MySQL-Connector Class.forName(driverName);
// Create a connection to the database logger.info("Attempting to connect to database, " + dbUrl + " as " + dbUser); connection = DriverManager.getConnection(dbUrl, dbUser, dbPass); if(!connection.isClosed()) { logger.debug("Database connection successful"); connected = true; } else { logger.fatal("Database connection failed"); } } catch (ClassNotFoundException e) { // Could not find the database driver logger.fatal("Could not load database driver, " + driverName); logger.fatal("Exception:" + e); throw e; // e.printStackTrace(); } catch (SQLException e) { // Could not connect to the database logger.fatal("Could not connect to database at, " + dbUrl + " as, " + dbUser); logger.fatal("Exception:" + e); // e.printStackTrace(); throw e; }
return connected; }
public boolean isConnected() { boolean connected = true; try { if(connection.isClosed()) { connected = false; } } catch (Exception e) { // Not doing anything with the exception connected = false; }
logger.debug("Database connected, " + connected); return connected; }
public boolean store(Lease lease) { boolean set = false; lease.dump(); set = true; return set; }
public boolean toAggDb(Lease lease) { boolean set = false; set = true; return set; }
public boolean updateLocalLeaseProcessedFlag(int localleaserecid) { boolean updated = false; String sql = "update local_lease set processed = 1 where id = ?";
try { PreparedStatement pstmt = connection.prepareStatement(sql); pstmt.setInt(1,localleaserecid); updated = pstmt.execute(); } catch (SQLException sqlx) { logger.fatal(sqlx); }
return updated; }
public ResultSet fetchLocalUnprocessed(int lastrecidnum) { this.dump(); ResultSet unprocessed = null; String sql = "select * from local_lease where id > ? and processed = 0";
logger.debug("Using connection, " + connection.toString());
try { PreparedStatement pstmt = connection.prepareStatement(sql); pstmt.setInt(1,lastrecidnum); logger.debug("SQL = " + pstmt.toString()); unprocessed = pstmt.executeQuery(); } catch (SQLException sqlx) { logger.fatal(sqlx); }
return unprocessed; }
public int purgeProcessed(String db) { int count = 0;
if(db.equalsIgnoreCase("local")) { logger.info("Purging local lease database"); String sql = "delete from local_lease where processed = 1"; try { Statement stmt = connection.createStatement(); count = stmt.executeUpdate(sql); } catch (SQLException sqlx) { logger.fatal(sqlx); } } else if (db.equalsIgnoreCase("agg")) { logger.info("Purging agg lease database"); } else { logger.warn("Uknown database for purging, "+ db); }
return count; }
public boolean toLocalDb(String leaseblob) { long t0 = System.currentTimeMillis(); boolean set = false; String sql = "insert into local_lease (processed, leaseblob) values(?,?)";
try { PreparedStatement pstmt = connection.prepareStatement(sql); pstmt.setInt(1,0); pstmt.setString(2, leaseblob); logger.debug("SQL = " + pstmt.toString()); set = pstmt.execute(); } catch(SQLException sqlx) { logger.fatal(sqlx); }
long t1 = System.currentTimeMillis(); long elapsed = t1 - t0; logger.debug("Elapsed time to complete processing, " + elapsed); return set; } }
IchBin - 16 Nov 2005 00:07 GMT > Source code for the DbClient class is below: > [quoted text clipped - 65 lines] > dbPass = pass; > } You need to add this check else you use the same database on any connect
if(name != null) { dbName = name; }
Also when connecting make sure your calls are separated that is..
*THIS WAY*
DbClient DbClientA = new DbClient(type, host, user, pass, name); try { DbClientA.connect(); } catch (Exception e) {} DbClient DbClientb = new DbClient(type, host, user, pass, name); try { DbClientb.connect(); } catch (Exception e) {}
*NOT THIS WAY* DbClient DbClientA = new DbClient(type, host, user, pass, name); DbClient DbClientb = new DbClient(type, host, user, pass, name); try { bClientA.connect(); DbClientb.connect(); } catch (Exception e) {}
 Signature Thanks in Advance... IchBin, Pocono Lake, Pa, USA http://weconsultants.servebeer.com/JHackerAppManager __________________________________________________________________________
'If there is one, Knowledge is the "Fountain of Youth"' -William E. Taylor, Regular Guy (1952-)
JJMB - 16 Nov 2005 02:01 GMT Thanks, regarding the latter. This is the way I was contructing the clients and it was not working. I am really at a loss.
PS - I fixed the first issue you pointed out, thanks.
IchBin - 16 Nov 2005 03:52 GMT > Thanks, regarding the latter. This is the way I was contructing the > clients and it was not working. I am really at a loss. > > PS - I fixed the first issue you pointed out, thanks. I do not understand. Your are getting the same results as I did and it is still not working for you. How are you using the DbClient instances..
I cut and pasted your code, then - Changed all of the Logger calls to System.out.Println()'s - Changed Database to HSQLDB, JDBC Driver and the dbUrl - Started the HSQLDB Server - Created a test class, see below, to prove it worked calling two different databases. And it did.
package dummy; public class TestingShell { static DbClient dbClientA; static DbClient dbClientB; public static void main(String[] args) { String type = "HSQLDB"; String host = "localhost"; String user = "SA"; String pass = ""; String name = "newjpeoplequotesdb"; dbClientA = new DbClient(type, host, user, pass, name); try { dbClientA.connect(); } catch (Exception e) {}
name = "systemdbfree"; dbClientB = new DbClient(type, host, user, pass, name); try { dbClientB.connect(); } catch (Exception e) {} } }
*Console* Database Host = localhost Database Type = HSQLDB Database Name = newjpeoplequotesdb Database User = SA Database Pass = Attempting to connect to database, jdbc:hsqldb:hsql://localhost/newjpeoplequotesdb as SA Database connection successful Database Host = localhost Database Type = HSQLDB Database Name = systemdbfree Database User = SA Database Pass = Attempting to connect to database, jdbc:hsqldb:hsql://localhost/systemdbfree as SA Database connection successful
 Signature Thanks in Advance... IchBin, Pocono Lake, Pa, USA http://weconsultants.servebeer.com/JHackerAppManager __________________________________________________________________________
'If there is one, Knowledge is the "Fountain of Youth"' -William E. Taylor, Regular Guy (1952-)
JJMB - 16 Nov 2005 04:19 GMT I am wondering if there is an issue Connection class in the MySQL Connector Driver? I did as you did in the example above.
John
IchBin - 16 Nov 2005 05:00 GMT > I am wondering if there is an issue Connection class in the MySQL > Connector Driver? I did as you did in the example above. > > John What was the output.. on the connections from my example.. you need to feed me more information.
Couple of other things. You need to have close connect method. Also, I would not use any of the logic for checking isConnected() or isClosed(). You either have it or you don't hence the catch exception based on the connection. You only issue one connect per DbClient object. And one close. That single connection should be encapsulated in their respective object.
 Signature Thanks in Advance... IchBin, Pocono Lake, Pa, USA http://weconsultants.servebeer.com/JHackerAppManager __________________________________________________________________________
'If there is one, Knowledge is the "Fountain of Youth"' -William E. Taylor, Regular Guy (1952-)
JJMB - 16 Nov 2005 05:15 GMT Apologies, for not providing more information. Basically, without pasting a great deal of useless log output the jist of the log messages is that the last DbClient that is created is the one that is utlimately used, seems like some sort of LIFO logic somewhere. I determined this by loggin the output of to toString method on the Connection.
Where does is the close() method required? In the calling application to signal the connection to close when I am done with it right?
Also, I did learn that the isClosed() method does not return what one might expect. I changed the logic of my isConnected() method to run a simple query, "select 1". If it throws an exception I set connect = false and return connected.
What do you mean when you say?
" You either have it or you don't hence the catch exception based on the connection. You only issue one connect per DbClient object. And one close. That single connection should be encapsulated in their respective object."
REALLY appreciate your time,
John
PS - I am also scavenging the mysql forums now, see if anythings pops up there.
IchBin - 16 Nov 2005 07:18 GMT > Apologies, for not providing more information. Basically, without > pasting a great deal of useless log output the jist of the log messages [quoted text clipped - 4 lines] > Where does is the close() method required? In the calling application > to signal the connection to close when I am done with it right? In DbClient
public void disconnectDB() { try { System.out.println("Closing db connection for DataBase: " + dbName); connection.close(); } catch (SQLException e) { System.out.println("Could not close connection to database, " + dbName); System.out.println("SQLException:" + e); ......
> Also, I did learn that the isClosed() method does not return what one > might expect. I changed the logic of my isConnected() method to run a [quoted text clipped - 9 lines] > respective > object." connection = DriverManager.getConnection(........... // // If no execption on connection then Database connected connected = true; System.out.println("Database connection successful"); } catch (ClassNotFoundException e) {
> REALLY appreciate your time, > > John > > PS - I am also scavenging the mysql forums now, see if anythings pops > up there. Not sure what is going on..
 Signature
Thanks in Advance... IchBin, Pocono Lake, Pa, USA http://weconsultants.servebeer.com/JHackerAppManager __________________________________________________________________________
'If there is one, Knowledge is the "Fountain of Youth"' -William E. Taylor, Regular Guy (1952-)
IchBin - 16 Nov 2005 09:13 GMT > Apologies, for not providing more information. Basically, without > pasting a great deal of useless log output the jist of the log messages [quoted text clipped - 25 lines] > PS - I am also scavenging the mysql forums now, see if anythings pops > up there. John, I just saw what the problem. I can't believe I missed this but the problem is all of your vars in DbClient are static .... Take the static off those vars and you will be fine. Or cut and past these. I will email you some code, I was testing with on this.
private final String D_DBURL = null; private Connection connection = null; private String driverName = "com.mysql.jdbc.Driver"; private final String D_DBTYPE = "mysql"; private final String D_DBHOST = "localhost"; private final String D_DBUSER = "test"; private final String D_DBPASS = "test"; private final String D_DBNAME = "test";
private String dbUrl = D_DBURL; private String dbHost = D_DBHOST; private String dbUser = D_DBUSER; private String dbPass = D_DBPASS; private String dbName = D_DBNAME; private String dbType = D_DBTYPE;
 Signature Thanks in Advance... IchBin, Pocono Lake, Pa, USA http://weconsultants.servebeer.com/JHackerAppManager __________________________________________________________________________
'If there is one, Knowledge is the "Fountain of Youth"' -William E. Taylor, Regular Guy (1952-)
JJMB - 16 Nov 2005 03:21 GMT Frankly I am starting to think it is the way I have defined Connection connection in the DbClient class.
HalcyonWild - 16 Nov 2005 15:50 GMT > Source code for the DbClient class is below: > [quoted text clipped - 32 lines] > private static Connection connection = null; > private static String driverName = "com.mysql.jdbc.Driver"; Remove the static before the Connection declaration. Connection should not be static here.
Roedy Green - 16 Nov 2005 20:04 GMT > private static final String CLASSNAME = DbClient.class.getName(); > public static Logger logger = Logger.getLogger(CLASSNAME); [quoted text clipped - 14 lines] > private static String dbName = D_DBNAME; > private static String dbType = D_DBTYPE; Figure out which of these are invariant over all connections and which change with each connection. The ones that change should not be static.
you will probably find your finals can be static but the rest should be instance.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Java custom programming, consulting and coaching.
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|