diff --git a/lib/OpenQA/Shared/Plugin/Gru.pm b/lib/OpenQA/Shared/Plugin/Gru.pm index 2c47963b323..2d4784824ad 100644 --- a/lib/OpenQA/Shared/Plugin/Gru.pm +++ b/lib/OpenQA/Shared/Plugin/Gru.pm @@ -144,20 +144,29 @@ sub _find_existing_minion_job ($self, $task, $args, $job_ids) { sub _add_jobs_to_gru_task ($self, $gru_id, $job_ids) { my $schema = OpenQA::Schema->singleton; - for my $id (@$job_ids) { - # Add job to existing gru task with the same args - my $gru_dep = eval { $schema->resultset('GruDependencies')->create({job_id => $id, gru_task_id => $gru_id}); }; - unless ($gru_dep) { - my $error = $@; - die $error - unless $error - =~ m/insert or update on table "gru_dependencies" violates foreign key constraint "gru_dependencies_fk_gru_task_id"/i; - # if the GruTask was already deleted meanwhile, we can skip - # the rest of the jobs, since the wanted task was done - log_debug("GruTask $gru_id already gone, skip assigning jobs (message: $error)"); - last; - } - } + # Wrap in txn_do so we can use savepoints in the method. Necessary for cases + # where we are not in a transaction. Otherwise it's a noop + $schema->txn_do( + sub { + $schema->svp_begin('try_gru_dependencies'); + for my $id (@$job_ids) { + # Add job to existing gru task with the same args + my $gru_dep + = eval { $schema->resultset('GruDependencies')->create({job_id => $id, gru_task_id => $gru_id}); }; + unless ($gru_dep) { + my $error = $@; + $schema->svp_rollback('try_gru_dependencies'); + die $error + unless $error + =~ m/insert or update on table "gru_dependencies" violates foreign key constraint "gru_dependencies_fk_gru_task_id"/i; + # if the GruTask was already deleted meanwhile, we can skip + # the rest of the jobs, since the wanted task was done + log_debug("GruTask $gru_id already gone, skip assigning jobs (message: $error)"); + last; + } + } + $schema->svp_release('try_gru_dependencies'); + }); } sub enqueue ($self, $task, $args = [], $options = {}, $jobs = []) {