How to run 2 SQL “SELECT”s atomically? Or any other better way to get number of rows before i process them

不问归期 提交于 2019-12-10 17:17:17

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!