challet's avatar

Transaction and model events

Hi,

Is there a way to work with both transaction and subscribers on eloquent "saved" event. In case the transaction fails and rollbacks, the subscriber handle method would still be fired without knowing about the transaction state.

For instance, in this simplified example, how to avoid sending an alert about a model who might be rollbacked.

DB::beginTransaction();
$a = new AModel():
try {
    $a->save();
} catch (Exception $e) {
    // for instance an SQL duplicate unique key
    DB::rollBack();
}
class PushASubscriber
{
    public function handle()
    {
        // send an alert about an AModel creation
    }
    
    public function subscribe($events)
    {
        $events->listen('eloquent.saved: AModel', 'PushASubscriber');
    }
}

I can think about two ways :

  • passing the transation along the event and re-use it in the subscriber
    • does Laravel allow it without hacking the base code ?
    • would it work for queued subscribers ? my guess is not
  • waiting for the transaction to be completed before to send the event
    • would break the purpose of "beforeSave" events (the saving one)
    • here again, hacking Laravel ?

Do you guys have thoughts about it ? any help welcome.

There is the begining of a discussion here but it has been closed without any details.

0 likes
4 replies
challet's avatar

I confused myself here, in fact the transaction would still be active in a subscriber (except the queued ones). So by rollbacking it would discard any subsequent operation made on the Db from the subscriber.

The problem kind of remain in that the "saved" event doesn't guarantee the model is actually saved. If the subsriber operations are about other storage, or external API, it can lead to reference a Db record which had existed during the transaction but has been rollbacked since.

Please or to participate in this conversation.