Java MYSQL / JDBC-запрос возвращает устаревшие данные из кэшированного соединения - PullRequest
5 голосов
/ 17 февраля 2012

Я искал в Stackoverflow ответ, но, похоже, не могу найти ответ, в котором нет Hibernate или какой-либо другой оболочки базы данных.

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

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

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

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

РЕДАКТИРОВАТЬ: в настоящее время я не использую транзакции для запросов.

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

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

Заранее спасибо за помощь!

Ответы [ 4 ]

9 голосов
/ 17 февраля 2012

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

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

conn.setAutoCommit(true);

или

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

Это позволяет сбрасывать запросы и предотвращать устаревание данных.

3 голосов
/ 15 февраля 2014

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

connection.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);

1 голос
/ 10 декабря 2015

Мой 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 решил мою проблему.

0 голосов
/ 17 февраля 2012

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...