我正在开发一个数据库导入工具。我正在通过设置JDBC获取大小来阅读Postgres DB。注意,出于测试目的,我将其设置为1
。我正在使用以下代码片段来读取底层Postgres DB:
try (final Connection connection = dataSource.getConnection()) {
final DatabaseMetaData metadata = connection.getMetaData();
connection.setAutoCommit(false);
final PreparedStatement statement = connection.prepareStatement("SELECT * FROM \"public\".\"table\" ORDER BY \"cursor\" ASC");
statement.setFetchSize(1);
final ResultSet rs = statement.executeQuery();
final ResultSetMetaData metaData = rs.getMetaData();
while (rs.next()) {
processResultSet(rs);
}
rs.close();
}
我想了解在具有实时更新的数据库上运行此工具时会发生什么。
为此,我在处理结果集和新的源数据库中并发更新的值时设置了一个断点。我最初的理论是,获取大小由限制和偏移量的组合来强制执行。我的期望是,对数据库的新更改将被我的代码拾取。因为我正在设置获取大小(导致查询以流模式执行),我还验证了对rs.next()
的每个调用都通过网络从Postgres DB获取数据。
但是,这个假设是错误的,我发现在我的简单JDBC迭代器中没有读取新值,这是因为给定的SQL查询是在单个事务中执行的吗?如果是,这是如何工作的?Postgres会一直跟踪过时的数据直到事务结束吗?这甚至适用于大型查询,例如select * from table
吗?提前感谢帮助-试图更好地理解这一点
1条答案
按热度按时间cgfeq70w1#
JDBC驱动程序直接读取PostgreSQL Frontend/Backend Protocol,发送的message为
Execute
:Execute (F)
Byte1('E')
将消息标识为“执行”命令。
Int32
以字节为单位的消息内容长度,包括自身。
String
要执行的门户的名称(空字符串选择未命名的门户)。
Int32
要返回的最大行数(如果门户包含返回行的查询)
(否则忽略)。零表示“无限制”。
获取大小只是作为最后一个4字节整数发送,服务器只返回那么多结果行,同一门户上的下一个
Execute
返回下一个批处理,以此类推。