diff --git a/Koha/Report.pm b/Koha/Report.pm index b8092f90bf..13c8a68f48 100644 --- a/Koha/Report.pm +++ b/Koha/Report.pm @@ -163,7 +163,16 @@ sub new_from_mana { =head3 prep_report Prep the report and return executable sql with parameters embedded and a list of header types -for building batch action links in the template +for building batch action links in the template. + +The returned SQL is suffixed with a tracking comment of the form + + /* { saved_sql.id: } { user_id: } */ + +L parses this comment out of +C to detect concurrent runs of the same +report. External log/audit tooling that consumes Koha SQL should treat +this format as part of the public contract. =cut diff --git a/reports/guided_reports.pl b/reports/guided_reports.pl index 414372bfb6..2d2346d054 100755 --- a/reports/guided_reports.pl +++ b/reports/guided_reports.pl @@ -827,6 +827,12 @@ if ( $op eq 'run' ) { my $duplicate_running_reports_per_user_limit = C4::Context->config('duplicate_running_reports_per_user_limit'); my $duplicate_running_reports; if ( $duplicate_running_reports_per_user_limit && C4::Context->userenv ) { + + # This is a TOCTOU check: between the count below and the actual + # query execution further down, a parallel request can slip past the + # limit. Worst case is one extra concurrent run, which is acceptable + # for the intended use case (preventing accidental double-clicks / + # multi-tab submissions) and avoids the cost of a serializing lock. $duplicate_running_reports = Koha::Reports->running( { report_id => $report_id,