2012-04-02 19 views
6

De acuerdo con la documentation para getResultSet en java.sql.Statement, que dice:getResultSet() "debe ser llamado sólo una vez por resultado"

Recupera el resultado actual como un objeto ResultSet. Este método debe llamarse solo una vez por resultado.

El uso de algunos código de prueba, me encontré con executeQuery() y varias llamadas a getResultSet() y observaron que el ResultSet regresado señaló al mismo objeto. Así que supongo que no devolverá un ResultSet diferente que necesitaría cerrar individualmente. Pero, por supuesto, esto podría ser exclusivo de mis controladores JDBC.

Mirando el documentation para ResultSet que dice: objeto ResultSet

Un defecto no es actualizable y tiene un cursor que se mueve hacia adelante solamente. Por lo tanto, puede recorrerlo solo una vez y solo desde la primera fila hasta la última fila.

Esto parece una buena razón por la que puede no ser una buena idea llamarlo varias veces ya que puede llevar a una situación de "error". Si esta fue la única razón, sentí que podrían haberlo dicho, así que creo que podría haber algo más que solo esto.

¿Alguien sabe por qué uno no debe llamar al getResultSet más de una vez por resultado? Este question es lo que me hizo curioso en primer lugar.

+1

No publicar esto como una respuesta porque es sólo una corazonada, pero sospecho que es de esta manera dar un margen de maniobra a los desarrolladores de controladores JDBC, lo que les permite no definir lo que sucede cuando lo llamas más de una vez. En su caso particular, funciona, pero si alguna vez cambió los controladores JDBC, podría no ser así. –

+1

Creo que es así de simple: el objeto ResultSet tiene estado. Solo hay un objeto ResultSet como miembro del Statement. Obtener el objeto no vuelve a ejecutar la declaración. No se garantiza que el objeto por segunda vez esté en el mismo estado que el primer get si modificó algo después del primer get. Entonces es solo una advertencia. Mirando el controlador jdbc de Postres (org.postgresql.jdbc2.AbstractJdbc2Statement), podemos ver que internamente realiza muchas llamadas como esta: return (result! = Null && result.getResultSet()! = Null); – Glenn

Respuesta

4

El objeto ResultSet es una interfaz proporcionada por Java JDBC; no proporcionan una implementación. Aunque su código de base de datos particular y los controladores asociados implementen ResultSet para que puedan llamarlo varias veces por resultado, si depende de un comportamiento que está fuera del contrato, ciertamente está jugando con fuego.

Una posible razón por la que el contrato se escribió con la línea this method should be called only once per result es por razones de eficiencia. La construcción de ResultSet probablemente hará una llamada JDBC RPC a la base de datos y los autores de la especificación JDBC querían desalentar múltiples viajes de ida y vuelta. Es posible que no hayan querido forzar a los implementadores a proteger contra múltiples llamadas por resultado de manera eficiente. Una vez más, a pesar de que su base de datos protege contra ese comportamiento, no significa que el próximo lo hará.

La mayoría de las implementaciones de ResultSet también mantienen una conexión a la base de datos abierta para que cuando obtenga ciertos campos (como blobs grandes) pueda devolver la llamada a la base de datos para obtener los datos. Tener múltiples conexiones abiertas o (lo que es peor) usar la misma conexión desde múltiples objetos ResultSet sería muy peligroso/confuso.

Además, pueden haber estado preocupados por dos partes de su código llamando al getResultSet() dos veces y se les devolvió una referencia al mismo objeto no sincronizado. Esto causaría confusión cuando se llamó al next() y sobrescribió el objeto con múltiples referencias.

Estoy especulando, por supuesto, pero espero que esto ayude.

+0

Definitivamente útil! Si recuerdo correctamente, al cerrar el 'ResultSet' no se cierran los posibles blobs creados. Estoy un poco confundido sobre el 3er párrafo con respecto a conexiones múltiples. ¿El 'ResultSet' no usaría la misma' Conexión' para recuperar datos de la base de datos? Además, no estoy seguro de por qué la misma 'Conexión' de múltiples' ResultSet' es mala, estoy seguro de que hay algo obvio que estoy pasando por alto. Además, si puede proporcionar un ejemplo (incluso si se trata de un controlador JDBC específico) de que llamar a 'getResult' dos veces sería problemático, creo que sería la respuesta perfecta. – nevets1219

+0

En el tercer párrafo, solo digo que la administración de la conexión es un problema. Tener múltiples copias del objeto 'Conexión' o si dos hilos cada uno tenía un' ResultSet' y estaban haciendo operaciones en la misma 'Conexión' no sincronizada sería peligroso. – Gray

+0

En términos de dar un ejemplo, no tengo el tiempo para eso. Esto es sobre la violación del contrato. Postgres podría actualizar su controlador y cambiar el comportamiento un poco, pero aún cumplir con el contrato y su código se rompería si dependiera de múltiples llamadas al trabajo. Es una cuestión de principios. – Gray

Cuestiones relacionadas