Improved removeOld method in BulkOperationRepository to fix subquery limitations in MySQL and optimize deletion logic.
This commit is contained in:
parent
ffc08ebff6
commit
a381ca7ef8
1 changed files with 26 additions and 21 deletions
|
|
@ -69,14 +69,27 @@ public class BulkOperationRepository {
|
|||
|
||||
@Transactional
|
||||
public void removeOld(Integer userId) {
|
||||
// First, update sys_error records to set bulk_operation_id to NULL
|
||||
// for bulk operations that will be deleted (all but the 10 newest for the current user)
|
||||
|
||||
// Build subquery to get the 10 newest operations
|
||||
String newestSubquery = "SELECT id FROM bulk_operation WHERE user_id = ? AND state NOT IN ('SCHEDULED', 'PROCESSING') ORDER BY created_at DESC ";
|
||||
String newestWithLimit = newestSubquery + dialectProvider.buildPaginationClause(10, 0);
|
||||
// First, fetch the IDs of the 10 newest operations to keep
|
||||
// (MySQL doesn't support LIMIT in IN/NOT IN subqueries)
|
||||
String fetchNewestSql = "SELECT id FROM bulk_operation WHERE user_id = ? AND state NOT IN ('SCHEDULED', 'PROCESSING') ORDER BY created_at DESC " +
|
||||
dialectProvider.buildPaginationClause(10, 0);
|
||||
Object[] paginationParams = dialectProvider.getPaginationParameters(10, 0);
|
||||
Object[] fetchParams = new Object[]{userId, paginationParams[0], paginationParams[1]};
|
||||
|
||||
List<Integer> newestIds = jdbcTemplate.queryForList(fetchNewestSql, Integer.class, fetchParams);
|
||||
|
||||
// If there are 10 or fewer operations, nothing to delete
|
||||
if (newestIds.size() <= 10) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Build comma-separated list of IDs to keep
|
||||
String idsToKeep = newestIds.stream()
|
||||
.map(String::valueOf)
|
||||
.reduce((a, b) -> a + "," + b)
|
||||
.orElse("0");
|
||||
|
||||
// Update sys_error records to set bulk_operation_id to NULL for operations that will be deleted
|
||||
String updateErrorsSql = String.format("""
|
||||
UPDATE sys_error
|
||||
SET bulk_operation_id = NULL
|
||||
|
|
@ -84,29 +97,21 @@ public class BulkOperationRepository {
|
|||
SELECT id FROM bulk_operation
|
||||
WHERE user_id = ?
|
||||
AND state NOT IN ('SCHEDULED', 'PROCESSING')
|
||||
AND id NOT IN (
|
||||
%s
|
||||
AND id NOT IN (%s)
|
||||
)
|
||||
)
|
||||
""", newestWithLimit);
|
||||
""", idsToKeep);
|
||||
|
||||
// Combine params: userId for outer query, userId + pagination params for subquery
|
||||
Object[] updateParams = new Object[]{userId, userId, paginationParams[0], paginationParams[1]};
|
||||
jdbcTemplate.update(updateErrorsSql, updateParams);
|
||||
jdbcTemplate.update(updateErrorsSql, userId);
|
||||
|
||||
// Then delete the old bulk_operation entries (keeping only the 10 newest for the current user)
|
||||
// Delete the old bulk_operation entries (keeping only the 10 newest for the current user)
|
||||
String deleteBulkSql = String.format("""
|
||||
DELETE FROM bulk_operation
|
||||
WHERE user_id = ?
|
||||
AND state NOT IN ('SCHEDULED', 'PROCESSING')
|
||||
AND id NOT IN (
|
||||
%s
|
||||
)
|
||||
""", newestWithLimit);
|
||||
AND id NOT IN (%s)
|
||||
""", idsToKeep);
|
||||
|
||||
// Combine params: userId for WHERE clause, userId + pagination params for subquery
|
||||
Object[] deleteParams = new Object[]{userId, userId, paginationParams[0], paginationParams[1]};
|
||||
jdbcTemplate.update(deleteBulkSql, deleteParams);
|
||||
jdbcTemplate.update(deleteBulkSql, userId);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue