【问题标题】:Java MYSQL/JDBC query is returning stale data from cached ConnectionJava MYSQL/JDBC 查询正在从缓存的连接返回陈旧数据
【发布时间】:2012-03-08 12:34:00
【问题描述】:

我一直在 Stackoverflow 上搜索答案,但似乎找不到不涉及 Hibernate 或其他数据库包装器的答案。

我通过 Tomcat 6 Java EE 应用程序中的 MYSQL 5.18 JDBC 驱动程序直接使用 JDBC。我正在缓存 Connection 对象,但不缓存 Statement 对象。查询的 ResultSet 在第一次运行时正确返回最新数据。当我通过 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();

提前感谢您的帮助!

【问题讨论】:

  • 你在使用事务吗?如果是这样,隔离级别是多少?这似乎有点像 REPEATABLE READ 行为。
  • 好问题。这些查询没有交易。我确实使用事务来进行更新/插入,但在这种特殊情况下,我现在没有在应用程序本身内执行任何操作。我正在通过一个外部工具进行更新,这可能会导致事情失败。如果您推荐事务作为防止脏读的解决方案,请分享答案。另外,我没有在连接上设置任何隔离级别。这会是问题吗?

标签: java mysql jdbc


【解决方案1】:

为什么不使用 Apache DBUtils 来使用 JDBC 池。它允许您使用相同的连接并控制连接大小。链接是http://commons.apache.org/dbutils

【讨论】:

  • 感谢您的指点。我可以尝试看看这段代码。但是,我正在尝试在没有更大的代码包装器的情况下在这里做一些非常简单的事情。
【解决方案2】:

原来这是一个未提交的查询问题。感谢 Brent Worden 提出的有关事务的问题,这让我环顾四周,发现我禁用了自动提交并且在查询后没有提交。

所以对我有用的解决方案:

conn.setAutoCommit(true);

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

这允许刷新查询并防止过时数据。

【讨论】:

  • 您可以将此标记为答案吗?这样,人们可以找到这篇文章并阅读您的问题和解决方案:)。
  • 我会在 2 天内。我现在不能,因为网站不让我这样做。
【解决方案3】:

设置事务隔离级别如下。

conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);

【讨论】:

    【解决方案4】:

    我的 mysql 安装:ENGINE=InnoDB,默认 tx_isolation=REPEATABLE_READ

    spring.xml

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

    如果使用池连接,它总是会返回相同的结果!

    change mysql tx_isolation=READ_COMMITTED 解决了我的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-04
      • 1970-01-01
      • 2015-04-07
      • 1970-01-01
      • 2015-06-16
      • 1970-01-01
      • 2019-01-24
      相关资源
      最近更新 更多