2011-01-26 8 views
5

Estoy usando una aplicación web Java en un servidor Tomcat y me gustaría saber cuál es la "mejor práctica" en términos de acceder a una conexión de base de datos desde el JNDI de Tomcat?Forma correcta de invocar el origen de datos JNDI dentro de Tomcat

Actualmente esto es básicamente lo que estoy haciendo cada vez que necesite acceder a la base de datos:

Context envContext = null; 
DataSource dataSource = null; 
try { 
    envContext = (Context)ctx.lookup("java:/comp/env"); 
    dataSource = (DataSource)envContext.lookup("jdbc/datasource"); 
    return dataSource.getConnection(); 
} catch (Exception e){ 
    e.printStackTrace(); 
    return null; 
}finally { 
    if(envContext != null){ 
     try{ 
      envContext.close(); 
     } catch (NamingException e){ 
      e.printStackTrace(); 
     } 
    } 
} 

Sin embargo, es esta la forma correcta para buscar una conexión desde JNDI cada vez que quiera acceder a la base de datos ? ¿Debo hacer una referencia al Contexto o al Datasource en su lugar?

Respuesta

3

Las búsquedas JNDI están Mapa esencialmente búsquedas de manera que su cabeza es mínimo. Pero es preferible obtener el DataSource una vez y "caché". En todo caso, escribir un método para devolver DataSource es ideal para no vincular demasiado código a las partes internas de J2EE y hacer que el código sea más fácil de probar.

+0

Exactamente el tipo de respuesta que estaba buscando, gracias. Otra pregunta, ¿hay mucho sobrecarga en la creación de un nuevo contexto cada vez que estoy haciendo acceso a los datos? – Avanst

+0

Relativamente hablando, no lo creo. Pero si lo marcaste y crearas un Contexto cada vez frente a simplemente almacenar en caché el origen de datos, sospecharía que verías una diferencia. Pero, en términos prácticos, la cantidad de veces que obtiene un DataSource (o Contexto) es mínimo en comparación con el resto de las actividades en el procesamiento de una solicitud. –

+3

Las búsquedas JNDI no son costosas, las búsquedas 'InitialContext' son ** MUY CARO ** en cada contenedor de aplicaciones y solo deben hacerse una vez al inicio de la aplicación. La mayoría de la gente no sabe la diferencia. –

1

su código de búsqueda se ve bien
En el contexto del problema, almacenamiento en caché de la fuente de datos parece bien, siempre que no se esté almacenamiento en caché el objeto de conexión real.

No he usado este enfoque desde hace tiempo. En estos días, como mínimo, que utilizan la primavera para inyectar el origen de datos/inicializar JdbcTemplate

+0

Sí, normalmente solo usaría una utilidad de terceros, como hibernar, pero para esto, no tengo permitido usar nada además de Java directo. – Avanst

2

Usted puede hacer algo como esto también: -

... 

Context initContext = new InitialContext(); 
DataSource dataSource = (DataSource) initContext.lookup("java:comp/env/jdbc/datasource"); 

... 
4

new InitialContext() es cara en cada contenedor de aplicaciones, que debe ser un static final y creado en un bloque static {}, con eficacia haciendo un Singleton. Solo debe crear esta referencia una vez y volver a usarla donde la necesite.

DataSource debe ser un static también. Debería tener un método public static Connection getConnection(); para recuperar objetos Connection, el código nunca debería tener que tratar con DataSource directamente. Esto funciona especialmente bien con las implementaciones PooledDataSource.

+0

¿Por qué es caro? No tiene que hacer mucho, y específicamente, ¿no tiene que hacer ninguna E/S de red? Sospecho que esto es mito urbano. – EJP

+0

@EJP No era un mito urbano, tenía un contrato donde uno de los desarrolladores "principales" (una persona de VB) escribía Servlets y estaba creando 'nuevo InitialContext()' en cada solicitud. Cada solicitud tomó casi un minuto. Se quejaba de lo lento que era Java, bla, bla, bla. Revisé su código y moví esa línea a una 'final estática privada' y un boom. La solicitud estaba en el rango 'cientos de milisegundos '. Esta fue una versión muy temprana de WebLogic por lo que podría no ser tan malo ahora debido a la Ley de Moore. Pero fue un problema reproducible cuando escribí esta respuesta en marzo de 2011. –

+0

No ha respondido mi pregunta. * ¿Por qué * es caro? y, para citarlo desde otro lugar, [YEINU: Su experiencia no es universal] (https: //blog.mozilla.org/nnethercote/2014/01/02/yeinu-your-experience-is-not-universal /). ¿Has probado realmente "cada contenedor de aplicaciones"? Sin eso, tu respuesta no tiene fundamento. ¿Y cómo '' new InitialContext() 'es costoso 'concuerda con su comentario anterior que' 'InitialContext' * las búsquedas * son ** MUY COSTOSAS **'? Decídete. – EJP

Cuestiones relacionadas