JavaDoc 说:"指示 ResultSet 对象的类型的常量,该对象可滚动,但通常对 ResultSet 底层数据的更改不敏感".
我对可滚动部分很清楚,但对声明的后半部分有疑问。我使用以下代码片段来验证我的理解。
conn = getConnection();
Statement stmt = conn
.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
String query = "select * from vehicle";
ResultSet rs = stmt.executeQuery(query);
rs.absolute(2);
System.out.print(rs.getString(2));
System.out.println("Waiting........");
Thread.sleep(20000); //1 manually changed database entry
rs.refreshRow();
System.out.println(rs.getString(2));//2 Surprisingly changes is reflected
在注释 1 中,我在数据库中进行了手动更改,然后调用了 rs.refreshRow() 方法。在此之后 在评论 2 中,当我访问第二列的值时,会反映第二列值的惊人变化。根据我的理解,这种变化不应该被反映,因为"它对其他人所做的改变不敏感"(根据JavaDoc)。谁能解释一下它的实际用途是什么?
我不久前对此进行了调查,特别是关于MySQL Connector/J。据我所知,设置ResultSet.TYPE_SCROLL_SENSITIVE
和ResultSet.TYPE_SCROLL_INSENSITIVE
实际上并没有影响从MySQL检索数据时的行为。
我发现的几个类似的问题和博客文章提到了MySQL Connector/J文档,在JDBC API实现说明部分中,它说
默认情况下,结果集完全检索并存储在内存中。在大多数情况下,这是最有效的操作方式,并且由于MySQL网络协议的设计,更容易实现。
它继续讨论使用 ResultSet.TYPE_FORWARD_ONLY
、ResultSet.CONCUR_READ_ONLY
和 stmt.setFetchSize(Integer.MIN_VALUE);
作为"向驱动程序逐行流式传输结果集的信号",但即使在这种情况下,我的测试表明,只要我stmt.executeQuery(...)
,整个 ResultSet 仍在检索。(尽管我可能错过了MySQL连接器/J文档的该部分中未明确提及的其他连接设置。
最后,我得出的结论是,ResultSet.TYPE_SCROLL_[IN]SENSITIVE
设置在MySQL Connector/J下真的没有任何区别。虽然只是在 ResultSet 周围滚动,但它似乎总是像是INSENSITIVE
的(忽略其他进程对现有行所做的任何更改),但rs.refreshRow();
总是返回最新数据(包括其他进程所做的更改),就好像它是SENSITIVE
一样,即使 ResultSet 应该是INSENSITIVE
的。