2012-02-17 4 views
5

Я искал Stackoverflow для ответа, но не могу найти тот, который не включает Hibernate или какую-либо другую оболочку базы данных.Запрос Java MYSQL/JDBC возвращает устаревшие данные из кэшированного соединения

Я использую JDBC напрямую через драйвер JSBC MYSQL 5.18 в приложении Java EE Tomcat 6. Я кэширую объекты Connection, но не кеширует объекты Statement. ResultSets для запроса корректно возвращают обновленные данные при первом запуске. Когда я изменяю несколько строк через PHPMyAdmin или какой-либо другой внешний инструмент, повторите запрос, я получаю устаревшие устаревшие данные.

Я использую обычные заявления, а не подготовленные состояния. Я пробовал ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE. Я также закрываю результирующий набор. Это не решает проблему. Я также попробовал ResultSet.refreshRows(), но это приводит к ошибке, потому что запрос имеет предложение JOIN.

Единственное, что однозначно решает проблему, заключается в закрытии соединения и повторном подключении к базе данных, что приводит к большой стоимости для каждой попытки запроса.

Есть ли способ повторного использования соединений без возврата устаревших данных?

EDIT: Я не использую транзакции для запросов на данный момент.

Вот общий код.

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

Благодарим за помощь заранее!

+2

Вы используете транзакции? Если да, то какой уровень изоляции? Это похоже на поведение REPEATABLE READ. –

+0

Хороший вопрос. Никаких транзакций для этих запросов.Я использую транзакции для обновлений/вставок в целом, но в этом конкретном случае я не выполняю какие-либо действия в самом приложении прямо сейчас. Я делаю UPDATE через внешний инструмент, который может отбросить все. Если вы рекомендуете транзакции в качестве решения для предотвращения грязных чтений, поделитесь им. Кроме того, я не устанавливал уровень изоляции в соединении. Будет ли это проблемой? – ricosrealm

ответ

9

Оказывается, это вопрос нерешенных запросов. Спасибо Brent Worden за вопрос о транзакциях, который заставил меня осмотреться и заметить, что я отключил автоматическую фиксацию и не выполнял запросы.

Так что решения, которые работали для меня:

conn.setAutoCommit(true); 

или

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

Это позволяет запросам промыть и предотвращаются несвежие данные.

+0

можете ли вы отметить это как ответ? таким образом, люди могут найти этот пост и прочитать вашу проблему и решение :). –

+0

Я через 2 дня. Я не могу в данный момент, потому что сайт не позволит мне. – ricosrealm

+0

Вы имеете в виду 'conn.commit();' right? –

0

Почему вы не используете пулы JDBC, используя Apache DBUtils. Он позволяет использовать одно и то же соединение, а также контролировать размер соединений. Ссылка: http://commons.apache.org/dbutils

+0

Спасибо за указатель. Я могу попытаться взглянуть на этот код. Однако я пытаюсь сделать что-то очень просто здесь без большой оболочки кода. – ricosrealm

3

Установите уровень изоляции транзакции, как показано ниже.

connection.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);

1

мой MySQL установки: ENGINE = InnoDB, по умолчанию tx_isolation = REPEATABLE_READ

spring.xml

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

, если использование объединенных соединение, которое всегда будет возвращать одинаковые результаты!

изменить mysql tx_isolation = READ_COMMITTED разрешил мою проблему.

Смежные вопросы