RED-6467: Split query into a select and a update query to prevent transaction rollbacks

This commit is contained in:
Viktor Seifert 2023-04-17 11:48:12 +02:00
parent a029bb5bf7
commit d8a0ec0467

View File

@ -19,10 +19,14 @@ import lombok.experimental.FieldDefaults;
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
class QueryExecutor {
private static final String UNDELETE_ENTRIES_QUERY = """
private static final String FETCH_ENTRY_VALUES_QUERY = """
select value from ::tableName::
where type_id = :typeId and value in (:entries)""";
private static final String UPDATE_ENTRIES_QUERY = """
update ::tableName::
set deleted = false, version = :version
where type_id = :typeId and value in (:entries) returning value""";
where type_id = :typeId and value in (:entries)""";
// Currently (2023-04-13) there is a limitation in the Postgres JDBC driver, that limits the number of elements in a "IN" clause
// to the max value of a 'short'. We subtract a small value to be on the safe side, since it is unclear what contributes
@ -39,11 +43,16 @@ class QueryExecutor {
@Transactional
public LinkedList<String> runUndeleteQueryInBatches(String typeId, Set<String> entries, long version, String tableName) {
String sqlString = getUndeleteEntriesQuery(tableName);
String fetchSql = getFetchEntryValuesQuery(tableName);
Query query = entityManager.createNativeQuery(sqlString);
query.setParameter("typeId", typeId);
query.setParameter("version", version);
Query fetchEntryValuesQuery = entityManager.createNativeQuery(fetchSql);
fetchEntryValuesQuery.setParameter("typeId", typeId);
String updateSql = getUpdateEntriesQuery(tableName);
Query updateEntriesQuery = entityManager.createNativeQuery(updateSql);
updateEntriesQuery.setParameter("typeId", typeId);
updateEntriesQuery.setParameter("version", version);
var results = new LinkedList<String>();
@ -56,8 +65,11 @@ class QueryExecutor {
break;
}
query.setParameter("entries", entryList.subList(fromIndex, toIndex));
results.addAll(query.getResultList());
fetchEntryValuesQuery.setParameter("entries", entryList.subList(fromIndex, toIndex));
results.addAll(fetchEntryValuesQuery.getResultList());
updateEntriesQuery.setParameter("entries", entryList.subList(fromIndex, toIndex));
updateEntriesQuery.executeUpdate();
fromIndex += ELEMENT_CHUNK_SIZE;
toIndex += ELEMENT_CHUNK_SIZE;
@ -67,9 +79,15 @@ class QueryExecutor {
}
private String getUndeleteEntriesQuery(String tableName) {
private String getFetchEntryValuesQuery(String tableName) {
return UNDELETE_ENTRIES_QUERY.replace("::tableName::", tableName);
return FETCH_ENTRY_VALUES_QUERY.replace("::tableName::", tableName);
}
private String getUpdateEntriesQuery(String tableName) {
return UPDATE_ENTRIES_QUERY.replace("::tableName::", tableName);
}
}