Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / First Aid / November 2005

Tip: Looking for answers? Try searching our database.

Issue managing multiple MySQL database connections

Thread view: 
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 Magazines

Get 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 ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.