Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

sagyLaravel's avatar

How to know Transaction Status?

i am using DB::transaction() but how to know transaction fails or is successful?

It does not allowed me to return true or false , As i know it returns Void .

Please suggest.

0 likes
8 replies
JarekTkaczyk's avatar

@sagyLaravel You don't need return value, just wrap it in try/catch block. If there's an exception thrown, it failed, otherwise, it was successful.

There are also 3 events that you can listen to:

connection.CON_NAME.beganTransaction
connection.CON_NAME.commited
connection.CON_NAME.rollingBack

Where CON_NAME is the connection name defined in your config/database.php, by default mysql, pgsql, sqlite and sqlsrv.

sagyLaravel's avatar

@JarekTkaczyk Yes , but i have written a function which includes transaction and i want to perform some operation on the bassis of the transaction returns it can be true / false.

for ex.

public function Test($data){ DB::transaction(function ($data) use ($data) { try{ // Do something }catch(Exception $e){ // Handle Exception }
}); }

$abc=$oMasterRoles->Test($data);

so in this case how do i will get value for $abc i need it to perform some operation on this value of $abc.

Please suggest what should i need to do?

JarekTkaczyk's avatar

@sagyLaravel Then return whatever you want to return from the function, depending on the try/catch.

Assuming you want true/false you simply do this:

/**
 * @return boolean
 */
public function transactionalQuery()
{
    try {
        DB::transaction(function ($data) {
            // do something
        });
    } catch (\Exception $e) {
        return false;
    }

    return true;
}
5 likes
ultrasamad's avatar

@JarekTkaczyk Cool. But assume I'm doing the transaction in my route file where I not necessarily calling a function, in that case how do I determine the status?

gilesrussi's avatar

If you use DB::beginTransaction() you can get the transaction level with this:

DB::transactionLevel()

If you are inside any transactions, you will receive the number you are in. Ex:

DB::beginTransaction()
DB::beginTransaction()
DB::transactionLevel() // will return 2
DB::commit() // doesn't commit
DB::transactionLevel() // will return 1
DB::commit() // finally, it commits to the database
DB::transactionLevel() // will return 0
5 likes
BenjaminS's avatar

I came her for a solution for my tests and got it working with the following code:


use Illuminate\Database\Events\TransactionCommitted;

public function test_function_is_ran_with_transactions(): void
{
    // Arrange
    $fake = Event::fake(TransactionCommitted::class);
    DB::setEventDispatcher($fake);
    $model = Database\Factories\ModelFactory::new()->create();

    // Act
    (new App\TransactionStub)->updateThroughTransaction($model);

    // Assert
    Event::assertDispatched(TransactionCommitted::class);
}

Also keep in mind that the RefreshDatabase and LazilyRefreshDatabase trait also works with transactions, which can destroy your other tests.

I added a function in our abstract TestCase to allow single tests to forcibly refresh the database after the test has run;

/**
 * Sometimes transactions are used, the refresh database trait should be reset after the test
 */
public function usesTransactions(): void
{
    $this->beforeApplicationDestroyed(function () {
        RefreshDatabaseState::$lazilyRefreshed = false;
        RefreshDatabaseState::$migrated = false;
    });
} 

Please or to participate in this conversation.