问题
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.
回答1:
how about
SELECT (SELECT COUNT(*) FROM table) c, * FROM table
来源:https://stackoverflow.com/questions/30359737/how-to-run-2-sql-selects-atomically-or-any-other-better-way-to-get-number-of