2012-02-17 11 views
5

He estado buscando Stackoverflow para obtener una respuesta pero parece que no puedo encontrar uno que no involucre a Hibernate ni a ninguna otra base de datos.La consulta Java MYSQL/JDBC está devolviendo datos obsoletos desde la conexión en caché

Estoy usando JDBC directamente a través del controlador JDBC MYSQL 5.18 en una aplicación Tomcat 6 Java EE. Estoy almacenando objetos de conexión en caché, pero no en caché. Los ResultSets para la consulta devuelven datos actualizados correctamente en la primera ejecución. Cuando cambio algunas filas a través de PHPMyAdmin o alguna otra herramienta externa, vuelva a ejecutar la consulta, obtengo datos caducados y desactualizados.

Estoy usando declaraciones normales, no declaraciones preparadas. He intentado ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE. También estoy cerrando el conjunto de resultados. Estos no resuelven el problema. También probé ResultSet.refreshRows(), pero eso da como resultado un error porque la consulta tiene una cláusula JOIN.

Lo único que resuelve claramente el problema es cerrar la conexión y volver a conectarla a la base de datos, lo que resulta en un gran costo para cada intento de consulta.

¿Hay alguna forma de volver a utilizar Connections sin devolver los datos obsoletos?

EDITAR: No estoy usando transacciones para consultas en este momento.

Aquí está el código general.

Connection conn; //created elsewhere and reused 
... 

String query = "SELECT p.ID as oid,rid,handle,summary,city,state,zip,t.name AS category  
       FROM profiles AS p 
       JOIN (terms AS t) ON (p.tid = t.ID) 
       WHERE p.ID = 1"; 

ResultSet resultSet; 
Statement s; 
synchronized (conn) 
{        
    s = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, 
          ResultSet.CONCUR_UPDATABLE);       
    resultSet = s.executeQuery(query); 
} 

//Iterate over the results using .next() and copy data to another data structure 
List retval = getResults(resultSet); 
s.close(); 

Gracias por la ayuda con anticipación!

+2

¿Está utilizando transacciones? Si es así, ¿cuál es el nivel de aislamiento? Parece un poco como el comportamiento REPEATABLE READ. –

+0

Buena pregunta. Sin transacciones para estas consultas.Utilizo transacciones para las actualizaciones/inserciones en general, pero en este caso particular no estoy ejecutando ninguna en la aplicación en este momento. Estoy haciendo las ACTUALIZACIONES a través de una herramienta externa que puede arrojar cosas. Si recomienda transacciones como una solución para evitar lecturas sucias, comparta una respuesta. Además, no he establecido ningún nivel de aislamiento en la conexión. ¿Ese sería el problema? – ricosrealm

Respuesta

9

Resulta que se trata de consultas sin compromiso. Gracias a Brent Worden por la pregunta sobre las transacciones que me llevó a mirar a mi alrededor y ver que había desactivado la confirmación automática y que no me estaba comprometiendo después de las consultas.

Así que las soluciones que trabajaban para mí:

conn.setAutoCommit(true); 

o

statement.executeQuery(query); 
conn.commit(); 

Esto permite que las consultas que se vacían y se evita datos obsoletos.

+0

¿Puedes marcar esto como la respuesta? de esa manera, las personas pueden encontrar esta publicación y leer su problema y solución :). –

+0

lo haré en 2 días. No puedo por el momento porque el sitio no me deja. – ricosrealm

+0

quieres decir 'conn.commit();' ¿verdad? –

0

¿Por qué no utiliza pools JDBC usando Apache DBUtils? Le permite usar la misma conexión y también controlar el tamaño de las conexiones. El enlace es http://commons.apache.org/dbutils

+0

Gracias por el puntero. Puedo probar y echar un vistazo a este código. Sin embargo, estoy tratando de hacer algo muy simple aquí sin un envoltorio de código más grande. – ricosrealm

3

Establezca el nivel de aislamiento de transacción como se indica a continuación.

connection.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);

1

mi instalación de MySQL: ENGINE = InnoDB, tx_isolation defecto = REPEATABLE_READ

spring.xml

<tx:method name="find*" propagation="SUPPORTS" read-only="true" timeout="600" /> 

si el uso combinado de conexión que siempre devolverá mismos resultados!

cambiar mysql tx_isolation = READ_COMMITTED resolvió mi problema.

Cuestiones relacionadas