I'm working on a database importer tool. I'm reading from a Postgres DB by setting the JDBC fetch size. Note that I've set it to 1 for testing purposes. I'm using this snippet of code to read from the underlying 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();
}
I wanted to understand what happens while running this tool on a database with live updates.
To do this, I set a breakpoint while processing the result set and concurrently updated values in the new source database. My initial theory was that the fetch size is enforced by a combination of limits and offsets. My expectation was that the new changes to the database would be picked up by my code, since I'm setting the fetch size (causing the query to be executed in streaming mode). I also verified that each call to rs.next() goes over the network to grab data from the Postgres DB.
However, this assumption was wrong. What I found is that the new values are not read in my simple JDBC iterator. Is that because the given SQL query is executing in a single transaction? If so, how does this work? Is Postgres keeping track of stale data until a transaction ends. Does this even apply for large queries e.g. select * from table? Appreciate the help in advance - trying to get a better understanding of this