Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Combining Transactions WITH Queues in Laravel

Is there a way to tell the Queue facade to not automatically persist what was pushed to the queue until I specifically tell it to?

Queue::noPersist()
Queue::push()
Queue::push()
Queue::persist()

See my problem is as follows, my code execution is wrapped in a transaction.

enter image description here

Inside this transaction is some eloquent records being added and right after also a job being pushed to the queue.

queue runs before transaction commits: The issue is that the queue sometimes starts running before my transaction finishes so it tries to reference a record that hasn't yet been "committed".

Provided my design is ok I'm thinking what I really need is for the queue to only submit after the transaction successfully commits: If the transaction fails then the job should also be rolled back so to speak. Or in other words the jobs shouldn't be pushed until after the transaction succeeds.

queue delay I saw laravel has a delay I can add to the queue but I didn't want to hack a random number in there as that's a bit fragile I really just want to only submit the queues if transaction succeeds.

Any guidance or built in features that could be useful to help me out here?

DB::transaction(function() {
    // add record A to DB
    // add JOB to QUEUE (this job starts firing before transaction commits and fails finding the record A)
    // more operations
});
like image 902
user391986 Avatar asked Mar 13 '23 02:03

user391986


1 Answers

Commit happens after your closure function, so if you keep using this structure - you won't be able to enqueue after commit.

However, Laravel got another way to do transactions (see 'Manually Using Transactions' in Laravel documentation). You could do something like:

$errors = false;

try {
  DB::beginTransaction();

  // All your operations here
} catch (Exception $e) {
  $errors = true;
  DB::rollBack();
}

if (!$errors) {
  DB::commit();

  // Add to queue
}
like image 117
Denis Mysenko Avatar answered Mar 28 '23 21:03

Denis Mysenko