private List<? extends AuditActionContext> getAuditRecordsSince(final StringBuilder where, final Object[] args,
                                                                    final long count) {
        return transactionTemplate.execute((TransactionCallback<List>) transactionStatus -> {
            var sql = String.format(selectByDateSqlTemplate, tableName, where);
            if (count > 0) {
                if (jpaAuditTrailEntityFactory.isOracle()) {
                    sql += " FETCH FIRST %s ROWS ONLY".formatted(count);
                } else if (jpaAuditTrailEntityFactory.isMsSqlServer()) {
                    sql = StringUtils.replace(sql, "SELECT ", "SELECT TOP %s ".formatted(count));
                } else {
                    sql += " LIMIT %s".formatted(count);
                }
            }
            val results = new ArrayList<>();
            LOGGER.debug("Executing SQL query [{}]", sql);
            jdbcTemplate.query(sql, resultSet -> {
                results.add(getAuditActionContext(resultSet));
            }, args);
            return results;
        });
    }
Instance of TransactionTemplate to manually execute a transaction since
threads are not in the same transaction.
support/cas-server-support-audit-jdbc/src/main/java/org/apereo/inspektr/audit/support/JdbcAuditTrailManager.java