2012-09-22 20 views
9

Si obtengo un objeto de conexión usando DriverManager.getConnection() y DataSource.getConnection(), ¿cómo difieren en el comportamiento cuando se llama a .close() en esos objetos?Comportamiento de conexión - DriverManager.getConnection() y DataSource.getConnection()

Antes de llamar al método .close(), obtuve objetos relevantes Statement y ResultSet de estas dos conexiones diferentes. Poco después de obtener estos dos objetos, si digo connection1.close() (a través de DriverManager.getConnection()), anulará el objeto de conexión y no se supone o tengo permiso para acceder a los objetos Statement y ResultSet relevantes. ¿Corrígeme si estoy equivocado?

Segundo escenario, ahora si digo connection2.close() (a través de DataSource.getConnection()), simplemente lo devuelve al grupo. Pero la conexión aún está en vivo. ¿Podré acceder a los objetos asociados Statement y ResultSet?

Respuesta

6

Si asumimos un (básico) DataSource (es decir: uno que no hace la agrupación de conexiones), entonces obtiene una conexión física que es la misma que la obtenida de DriverManager (algunos los controladores incluso usan internamente DriverManager de DataSource, o DataSource de DriverManager). Entonces esas conexiones se comportarán de manera idéntica.

Ahora, si suponemos un DataSource que proporciona la agrupación de conexiones, el DataSource usa un ConnectionPoolDataSource (o un mecanismo interno similar) para obtener un PooledConnection. Este PooledConnection administra la conexión física real a la base de datos.

Cuando un usuario solicita una conexión de DataSource, DataSource obtendrá una conexión compartida y le pedirá un Connection. El PooledConnection luego creará una conexión lógica que usa o envuelve la conexión física (por ejemplo, usando un Proxy). El DataSource devolverá esa conexión lógica al usuario.

Para el usuario, la conexión lógica debe comportarse de forma idéntica a una conexión física en todos los aspectos. Por lo tanto, cuando un usuario cierra la conexión, esa conexión lógica y todos los objetos JDBC dependientes se cerrarán y se comportarán de forma idéntica a un cierre de conexión física.

JDBC 4.1 apartado 11.1 dice:

La agrupación de conexiones es completamente transparente para el cliente: El cliente obtiene una conexión agrupada y lo utiliza de la misma forma en que se obtiene y utiliza una conexión no agrupada.

Y la sección 11.4:

Si la aplicación intenta volver a utilizar el mango lógica, la aplicación de conexión lanza una excepción de SQL.

y

Para un objeto PooledConnection dado, sólo el objeto de conexión lógico producido más recientemente será válida. Cualquier objeto de conexión previamente existente se cierra automáticamente cuando se llama al método PooledConnection.getConnection asociado.

En el fondo, sin embargo, cuando la conexión lógica se cierra, el PooledConnection señalará el origen de datos que está disponible para su reutilización, y la fuente de datos será entonces volver a la agrupación de conexiones, o cerrar la PooledConnection (que cierra la conexión física) si ya no necesita la conexión.

El DataSource también puede revocar forzosamente una conexión de un usuario (por ejemplo, cuando una conexión se retira demasiado tiempo, etc.), solicitando a PooledConnection que cierre la conexión lógica.

+0

En mi aplicación, puedo acceder a mi objeto 'ResultSet' incluso después de cerrar mi objeto' Conexión'. Entonces, según su nota, ¿Websphere falló esta implementación? – Sriram

+0

Eso depende de lo que quiera decir con acceso. El objeto ResultSet seguirá existiendo, pero no podrá usar el ResultSet ya que debería haberse cerrado cuando se cerró la conexión lógica. –

+1

Y si se trata de una implementación incorrecta de WebSphere: eso depende de lo que use como 'ConnectionPoolDataSource' para' DataSource' de websphere. El comportamiento que describí debe ser aplicado por la implementación 'PooledConnection'. –

3

connection1.close() (a través de DriverManager.getConnection()),

esto se cerrará la conexión física establecida para la base de datos y todos los recursos a saber. Conjunto de resultados, declaración, conexión son liberados. Por lo tanto, no puede acceder a ellos una vez que se cierra la conexión.

connection2.close() (a través de DataSource.getConnection())

Esta fuente de datos depende de la implementación y por lo tanto el comportamiento no tiene que ser consistente a través de diferentes implementaciones de DataSource. Además, dentro de una implementación de DataSource determinada, el ciclo de vida real de la conexión depende de varios otros parámetros, por lo que se recomienda encarecidamente no diferenciar esta conexión de la obtenida a través de DriverManager.

Si realmente desea que los datos contenidos en el ResultSet estén disponibles después de la Statement y Connection están cerrados, se puede echar un vistazo a si CachedRowSet que se adapte a su caso de uso.

+2

Las conexiones lógicas obtenidas de un conjunto de conexiones deben comportarse (para el usuario) exactamente igual que las conexiones físicas obtenidas de DriverManager. Por lo tanto, para el usuario, la conexión y todos los objetos dependientes deben aparecer cerrados, incluso si la conexión física permanece abierta. Si una implementación de origen de datos se comporta de otra manera, no cumple con la especificación JDBC. –

3

El almacenamiento en caché del lado del cliente puede depender del controlador que se está utilizando para la conexión no está seguro. Pero algunos controladores impiden específicamente que use una declaración o conjunto de resultados una vez que se ha cerrado la conexión. Otros mantienen el resultado en el lado del cliente

Cuestiones relacionadas