Как запустить 2 SQL "SELECT" с атомарным? Или любой другой лучший способ получить количество строк до их обработки

Я пытаюсь запустить 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...

Мой вопрос - лучший способ?

В настоящее время я узнал, что могу:

connection.setAutoCommit(false);
connection.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE)
// call 2 SQL queries above
connection.commit();

Этот способ, похоже, работает. Я тестировал, что другой поток заблокирован для выполнения INSERT между первым SELECT и commit(). Это правильный и оптимальный способ? Могу ли я быть уверенным, что таким образом мой COUNT всегда будет таким же, как число строк, возвращаемое из следующего выбора?

Также я ожидал бы, что вместо Connection.TRANSACTION_SERIALIZABLE будет Connection.TRANSACTION_REPEATABLE_READ. Но это не работает в Дерби 10.11.1.1. Это ошибка? Я новичок в бизнесе базы данных, но он работает как ожидается для базы данных H2 - поэтому я ожидаю, что это может быть ошибка в дерби...

Обратите внимание, что я уже знаю о решении, где вы можете:

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()){...}

Но это решение не является оптимальным. Для дерби я измерил его ~ 7 раз медленнее. Для H2 это ~ 2 раза медленнее.

Ответ 1

как насчет

SELECT (SELECT COUNT(*) FROM table) c, * FROM table