Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scope of Connection Static variable inside static method for the entire application?

Tags:

java

jdbc

I am having the following approach for logging certain things from my java application to Oracle DB.

Package com.util.dblog;
public class DBLog {

static Connection con = null;
static PreparedStatement stmt = null;

static { 
 try{
      DBConnectionHelper connHelper = DBConnectionHelper.createInstance();
    con=connHelper.getConnection("ds"); //Getting connection from connection pool
    con.setAutoCommit(false);
    }
catch(Exception e)
{}  
       } 

public static void logmethod1(String param1, String param2) { 

if (con == null || con.isClosed()) {
 DBConnectionHelper connHelper = DBConnectionHelper.createInstance();
    con=connHelper.getConnection("ds");
    con.setAutoCommit(false);
}

String SQL_PREP_INSERT = "INSERT INTO tableA (LOG_ID,USER_ID,EXEC_TIME) VALUES"             + " (logid_seq.nextval, ?, ?)"; 
stmt = con.prepareStatement(SQL_PREP_INSERT); 
stmt.execute();
stmt.close();
}

public static void logmethod2(String param1, String param2, String param3) { 

if (con == null || con.isClosed()) {
 DBConnectionHelper connHelper = DBConnectionHelper.createInstance();
    con=connHelper.getConnection("ds");
    con.setAutoCommit(false);
}

...
...
}

public saveCon() {
con.commit();
}
public closeCon() {
   con.close();
}

} //End of DBLog class

From my Java application class, I am calling as follows,

import com.util.dblog;
public class myApp{
DBLog.logmethod1(param1, param2);
....
DBLog.logmethod2(param1, param2, param3);
...
} //End of myApp class

And I am calling saveCon() at request level inside Filter class and closeCon() inside destroy() method of sessionListener class. Instead of comitting the connection object inside logmethod1 and logmethod2, I am doing this just to reduce the commit frequency. This methods will be called some 5-10 times in my application. So I will be commiting once in 10 times instead of 10 times per request. Suppose there is another http request there wil be another commit once the 10 logs are inserted. And finally I am closing the connection once session is about to be destroyed.

Now the question I am having is, the connection object "con" that is created in static block of DBLog class will be available for the static methods logmethod1 and logmethod2 ? I hope its created when the class is loaded first and will be available throughout the application scope? Because there will be many users coming in and I am worried if this approach is correct, or any other approach is needed? Please let me know if its not clear and I will get back.

like image 858
Gopi Avatar asked Dec 04 '25 06:12

Gopi


1 Answers

static {} block will be called before your methods, but this is a bad idea to use your class this way. Avoid static constructions when you can substitute them with classic constructions. You can change all variables and methods to non-static, block static {} change to constructor and your App will be something like:

import com.util.dblog;
public class myApp{

    DBLog log = new DBLog();

    log.logmethod1(param1, param2);
    log.logmethod2(param1, param2, param3);

} //End of myApp class

There is a great book called Java Puzzlers at this site, I advise you to read it. It has a small chapter related to your question, it will take about 3 minutes to read.

Java Puzzlers Go to Puzzle 5: Larger Than Life

Your program will work normally I think.

There is an alternative without static blocks:

Package com.util.dblog;
public class DBLog {

Connection con = null;
PreparedStatement stmt = null;

public DBLog () {
    init();
}

private void init() {
    try {
        DBConnectionHelper connHelper = DBConnectionHelper.createInstance();
        con=connHelper.getConnection("ds"); //Getting connection from connection pool
        con.setAutoCommit(false);
    } catch(Exception e) {}  
}

public void logmethod1(String param1, String param2) { 

    if (con == null || con.isClosed()) {
        init();
    }

    String SQL_PREP_INSERT = "INSERT INTO tableA (LOG_ID,USER_ID,EXEC_TIME) VALUES"             + " (logid_seq.nextval, ?, ?)"; 
    stmt = con.prepareStatement(SQL_PREP_INSERT); 
    stmt.execute();
    stmt.close();
}

public void logmethod2(String param1, String param2, String param3) { 

    if (con == null || con.isClosed()) {
        init();
    }
    ...
    ...
}

public void voidsaveCon() {
    con.commit();
}
public void closeCon() {
    con.close();
}

} //End of DBLog class

From my Java application class, I am calling as follows,

import com.util.dblog;
public class myApp {

    ...
    // in some method
    DBLog log = new DBLog();
    log.logmethod1(param1, param2);
    ....
    log.logmethod2(param1, param2, param3);
    ...

} //End of myApp class

If you want to send your variable you must not create another instance. You can send variable in 2 ways:

SomeAnotherClass {

    // after initialize you can use this log, this log is same as in myApp class
    DBLog log;

    // 1 way: by sending to constructor
    public SomeAnotherClass(DBLog log) {
        this.log = log;
    }

    // 2 way: by calling set method
    public void setLog(DBLog log) {
        this.log = log;
    }
}
like image 63
alaster Avatar answered Dec 05 '25 20:12

alaster



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!