2012-02-17 10 views
5

Ho cercato StackOverflow per una risposta ma non riesco a trovarne uno che non coinvolga Hibernate o qualche altro wrapper del database.La query Java MYSQL/JDBC restituisce dati obsoleti dalla cache Connessione

Sto utilizzando JDBC direttamente tramite il driver JDBC MYSQL 5.18 in un'app Java EE Tomcat 6. Sto memorizzando nella cache gli oggetti Connection, ma non memorizzando nella cache gli oggetti Statement. I ResultSet per la query restituiscono correttamente dati aggiornati alla prima esecuzione. Quando cambio alcune righe tramite PHPMyAdmin o qualche altro strumento esterno, rieseguo la query, ottengo dati obsoleti non aggiornati.

Sto usando normali istruzioni, non PreparedStatements. Ho provato ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE. Sto anche chiudendo il set di risultati. Questi non risolvono il problema. Ho anche provato ResultSet.refreshRows(), ma questo si traduce in un errore perché la query ha una clausola JOIN.

L'unica cosa che risolve chiaramente il problema è chiudere la connessione e riconnettersi al database, il che si traduce in un costo elevato per ogni tentativo di query.

C'è un modo per riutilizzare Connections senza restituire dati obsoleti?

MODIFICA: al momento non sto utilizzando transazioni per le query.

Ecco il codice generale.

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(); 

Grazie per l'aiuto in anticipo!

+2

Stai utilizzando le transazioni? Se sì, qual è il livello di isolamento? Sembra un po 'come il comportamento di REPEATABLE READ. –

+0

Buona domanda. Nessuna transazione per queste query.Io uso le transazioni per gli aggiornamenti/inserti in generale, ma in questo caso particolare non sto eseguendo alcuna all'interno della stessa app in questo momento. Sto facendo gli AGGIORNAMENTI tramite uno strumento esterno che potrebbe buttare via le cose. Se si raccomandano transazioni come soluzione per evitare letture sporche, si prega di condividere una risposta. Inoltre, non ho impostato alcun livello di isolamento sulla connessione. Questo sarebbe il problema? – ricosrealm

risposta

9

Si è scoperto che si trattava di domande non vincolate. Grazie a Brent Worden per la domanda sulle transazioni che mi hanno spinto a guardarmi intorno e ho notato che avevo disabilitato il commit automatico e non mi ero impegnato dopo le query.

Quindi le soluzioni che hanno funzionato per me:

conn.setAutoCommit(true); 

o

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

In questo modo le query per essere lavati fuori e dati stantio è impedito.

+0

puoi contrassegnarlo come risposta? in questo modo, le persone possono trovare questo post e leggere il tuo problema e la soluzione :). –

+0

lo farò tra 2 giorni. Al momento non posso perché il sito non me lo consente. – ricosrealm

+0

intendi 'conn.commit();' giusto? –

0

Perché non utilizzare i pool JDBC utilizzando Apache DBUtils. Ti consente di utilizzare la stessa connessione e anche di controllare le dimensioni delle connessioni. Il collegamento è http://commons.apache.org/dbutils

+0

Grazie per il puntatore. Posso provare e dare un'occhiata a questo codice. Comunque sto cercando di fare qualcosa di molto semplice qui senza un wrapper di codice più grande. – ricosrealm

3

Impostare il livello di isolamento della transazione come di seguito.

connection.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);

1

la mia installazione di MySQL: ENGINE = InnoDB, tx_isolation default = REPEATABLE_READ

spring.xml

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

se l'uso in pool di connessione che sarà sempre tornare stessi risultati!

modifica mysql tx_isolation = READ_COMMITTED ha risolto il mio problema.

Problemi correlati