• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 997
  • Last Modified:

Proper use of Datasources

I am working on a J2EE application in WebSphere 5.1
My application uses a datasource to access its database.
This is the method executed every time the app needs to acquire a connection to the databse:

public static Connection getDBConnection(boolean autoCommit) throws NamingException, SQLException
{
      Hashtable parms = new Hashtable();
      parms.put(Context.INITIAL_CONTEXT_FACTORY,"com.ibm.websphere.naming.WsnInitialContextFactory");
      InitialContext ctx = new InitialContext(parms);
      DataSource ds = (DataSource)ctx.lookup("java:comp/env/MyDataSource");
      Connection conn = ds.getConnection();
      if (!autoCommit)
      {
            conn.setAutoCommit(false);
      }
      return conn;
}

Question:
Shouldn't it be way more efficient and logical to save the acquired datasource permanently to be used in the future?
Is there any problem with that approach?

I think the following modification of the original code is way more efficient:

public static Connection getDBConnection2(boolean autoCommit) throws NamingException, SQLException
{
      Hashtable parms = null;
      if(savedDataSource == null) //savedDataSource is a private static field in this class
      {
            parms = new Hashtable();
            parms.put(Context.INITIAL_CONTEXT_FACTORY,"com.ibm.websphere.naming.WsnInitialContextFactory");
            InitialContext ctx = new InitialContext(parms);
            savedDataSource = (DataSource)ctx.lookup("java:comp/env/MainAppDataSource");
      }
      Connection conn = savedDataSource.getConnection();
      if (!autoCommit)
      {
            conn.setAutoCommit(false);
      }
      return conn;
}

Does somebody sees any problem with the second version, which keeps the datasource reference for the rest of the application's life?
0
dyma82
Asked:
dyma82
1 Solution
 
boonlengCommented:
Great job, you manage to impove the codes by yourself.

The second version is similar to the codes for J2EE pattern - ServiceLocator. It cached the datasource to avoid performance overhead related to initial context creation and service lookups. The following is the codes that Im using. The ServiceLocator also consist methods to lookup EJB..etc.

public final class ServiceLocator {

    /** Logger */
    private static Log log = LogFactory.getLog(ServiceLocator.class);

    /** Instance of this class */
    private static ServiceLocator instance;

    /** <code>InitialContext</code> instance */
    private InitialContext initContext;

    /** Map to store the lookup instance */
    private Map cache;

    static {
        try {
            instance = new ServiceLocator();
        } catch (ServiceLocatorException e) {
            log.fatal(e);
        }
    }

    /**
     * Constructor for ServiceLocator.
     * @throws ServiceLocatorException Throw when NamingException
     */
    public ServiceLocator() throws ServiceLocatorException {
        try {
            Hashtable env = new Hashtable();
            if (SystemConstant.CONTEXT_PROVIDER_URL != null) {
                env.put(Context.PROVIDER_URL,
                    SystemConstant.CONTEXT_PROVIDER_URL);
            }

            if (SystemConstant.INITIAL_CONTEXT_FACTORY != null) {
                env.put(Context.INITIAL_CONTEXT_FACTORY,
                    SystemConstant.INITIAL_CONTEXT_FACTORY);
            }

            initContext = new InitialContext(env);

            cache = Collections.synchronizedMap(new HashMap());
        } catch (NamingException e) {
            throw new ServiceLocatorException(e);
        } catch (Exception e) {
            throw new ServiceLocatorException(e);
        }
    }

    /**
     * Retrives a new instance of this object.
     * @return Instance of this class
     */
    public static ServiceLocator getInstance() {
        return instance;
    }

     /**
     * DataSource Locator - Retrives the data source with the given JNDI name.
     * @param dataSourceName DataSource Name
     * @return DataSource
     * @throws ServiceLocatorException Throw when NamingException
     */
   public DataSource getDataSource(String dataSourceName)
        throws ServiceLocatorException {
        DataSource dataSource = null;
        try {
            if (cache.containsKey(dataSourceName)) {
                dataSource = (DataSource) cache.get(dataSourceName);
            } else {
                dataSource = (DataSource) initContext.lookup(dataSourceName);
                cache.put(dataSourceName, dataSource);
            }
        } catch (Exception e) {
            throw new ServiceLocatorException(e);
        }
        return dataSource;
    }
}
0
 
damonfCommented:
No reason you shouldn't do it that way.  DataSource is a factory ... all of your lookups return a reference to the same object anyway.  So your way is fine.
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now