Skip to content
This repository was archived by the owner on Jul 16, 2021. It is now read-only.
This repository was archived by the owner on Jul 16, 2021. It is now read-only.

Eloquent events aware of database transactions. #1441

Closed
@TitasGailius

Description

@TitasGailius

I has a situation where a database transaction fails but an eloquent event is still being dispatched.

To illustrate this problem take this test into consideration:

    /** @test */
    public function it_fires_an_eloquent_event_for_committed_transactions()
    {
        Event::fake();

        DB::transaction(function () {
            factory(User::class)->create();
        });

        Event::assertDispatched("eloquent.created: App\User");
    }

Everything works as expected. The user gets stored into the database and an event is fired.

Although if we manually fail the transaction, an event would still be fired:

    /** @test */
    public function it_fires_an_eloquent_event_for_committed_transactions()
    {
        Event::fake();

        DB::beginTransaction();
        factory(User::class)->create();
        DB::rollBack();

        Event::assertDispatched("eloquent.created: App\User");
    }

Problem:

The user is not stored into the database but an event is still being fired.

This creates situations where a specific action would be done even if they shouldn't. "Welcome email" is a perfect example, it would try to send the email even if the user is not there.

Suggestion:

Collect pending eloquent events and dispatch them only after the transaction is committed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions