Я наблюдал странное поведение с SQL Сервером и JDB C - связанное с большими отдельными запросами и пакетными обновлениями.
То, что у нас есть, не очень большое (около 2 миллионов строк) ) таблица, которая состоит из большого количества хранимых чисел nvarchar. В этом столбце есть некластеризованный индекс. Я выбираю все отличительные значения и выполняю обновления этих значений в пакетных пакетах.
Однако иногда кажется, что обновленные значения отражаются в возвращаемом наборе результатов.
Пример кода:
config.setMaximumPoolSize(3);
config.setAutoCommit(false);
final HikariDataSource hikariDataSource = new HikariDataSource(config);
final Connection selectConn = hikariDataSource.getConnection();
final PreparedStatement selectStmt = selectConn.prepareStatement("SELECT DISTINCT A FROM EXAMPLE_TABLE WHERE A IS NOT NULL", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
final ResultSet resultSet = selectStmt.executeQuery();
do {
List<String> valuesToUpdate = new ArrayList<>();
for (int i = 0; i < 10000 && resultSet.next(); i++) {
final String valueToUpdate = resultSet.getString(1);
valuesToUpdate.add(valueToUpdate);
if (valueToUpdate.equals("31081273963")) {
throw new IllegalArgumentException("This should be never thrown.");
}
}
if (valuesToUpdate.isEmpty()) {
return;
}
Connection updateConn = hikariDataSource.getConnection();
final PreparedStatement batchStatement = updateConn.prepareStatement("UPDATE EXAMPLE_TABLE SET A = '31081273963' WHERE A = ?");
for (String str: valuesToUpdate) {
batchStatement.setObject(1, str);
batchStatement.addBatch();
}
batchStatement.executeBatch();
updateConn.commit();
updateConn.close();
} while (true);
В вышеприведенном примере "31081273963" гарантированно не находится в базе данных до выполнения кода на 100%. Я устанавливаю все полученные значения в это значение "31081273963". Но иногда я сталкиваюсь с этим if (valueToUpdate.equals("31081273963"))
условием.
Самым странным является то, что я могу получить это исключение с примером значения «31081273963», который находится в середине упорядоченного запроса (когда он будет в таблица), но когда я выбираю значение ближе к началу, не исключение. (Конечно, я не говорю, что это значение «специальное», но я имею в виду, что мне нужно выбрать значение, которое не находится в начале набора результатов, чтобы вызвать это исключение.
Является ли это поведение в некоторой степени задокументированным или зависит от какого-то параметра? * * * * * * * * * * * * * * * * * * * * * * * * * * * * *1019*. (Реальная проблема XY - сделать resultSet нетронутым для полной прокрутки, с обновлениями в фоновом режиме, но без блокировки таблицы - но мне просто любопытно, почему и когда эта проблема возникает.)