I'm trying to run atomically
ResultSet resSet;
resSet = statement.executeQuery("SELECT COUNT(*) FROM table");
resSet.next()
long rowCount = resSet.getLong(1);
resSet = statement.executeQuery("SELECT * FROM table");
// read data of known row count...
My question is what is the best way?
Currently I found out I can do:
connection.setAutoCommit(false);
connection.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE)
// call 2 SQL queries above
connection.commit();
This way seems to work. I tested that another thread is blocked to perform INSERT
in between first SELECT
and commit()
.
Is that correct and optimal way? Can I be sure that this way my COUNT will always be same as rows count returned from next select?
Also I would expect that instead of Connection.TRANSACTION_SERIALIZABLE
the Connection.TRANSACTION_REPEATABLE_READ
shall be sufficient.
But it does not not work in Derby 10.11.1.1. Is it a bug? I'm new to database business but it works as expected for H2 database - therefore I expect it might be a derby bug...
Note that I already know about solution where you can do:
statement = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
resultSet = statement.executeQuery("SELECT * FROM table");
if (ResultSet.last()) {
int rowCount = ResultSet.getRow();
ResultSet.beforeFirst();
}
while(ResultSet.next()){...}
But this solution is not optimal. For derby I measured it is ~7 times slower. For H2 it is ~2 times slower.