Laravel 4.2 - Problem of rolling back transactions with multiple databases

I am having problems rolling back a transaction involving tables from multiple databases. Rolling back the primary table behaves as expected, but the child row remains and is now orphaned.

public function devUserCreateTest()
{
    DB::beginTransaction();

    try {

        $childUser  = new ChildUser; // Exists in database B
        $parentUser = new User; // Exists in database A

        $parentUser->setEmailAttribute('mike@yourmomshouse.com');

        $parentUser->save();

        $childUser->parent_user_id = $parentUser->id;

        $message = sprintf('Parent user id: %s', serialize($childUser->id));

        $childUser->save();

        $message = sprintf('Core user id: %s | hta user id: %s', serialize($parentUser->id), serialize($childUser->id));

        throw new Exception('Testing....');

        DB::commit();

    } catch (Exception $e) {

        Log::warning(sprintf('Exception: %s', $e->getMessage()));

        DB::rollback();
    }

    return $this->buildResponse(array('message' => $message));
}

      

It looks like it works:

public function devUserCreateTest()
{
    $dboA = DB::connection();
    $dboB = DB::connection('b_database');

    $dboA->beginTransaction();
    $dboB->beginTransaction();

    try {

        $childUser  = new ChildUser; // Exists in database B
        $parentUser = new User; // Exists in database A

        $parentUser->setEmailAttribute('mike@yourmomshouse.com');

        $parentUser->save();

        $childUser->parent_user_id = $parentUser->id;

        $message = sprintf('Parent user id: %s', serialize($childUser->id));

        $childUser->save();

        $message = sprintf('Core user id: %s | hta user id: %s', serialize($parentUser->id), serialize($childUser->id));

        throw new Exception('Testing....');

        $dboA->commit();
        $dboB->commit();

    } catch (Exception $e) {

        Log::warning(sprintf('Exception: %s', $e->getMessage()));

        $dboA->rollback();
        $dboB->rollback();
    }

    return $this->buildResponse(array('message' => $message));
}

      

+3


source to share


1 answer


You will also need to set up a transaction on database B.

Since you are not posting any code ChildUser

, here's an example:

app / models / ChildUser.php:



class ChildUser extends Eloquent
{
    protected $connection = 'some_connection'; // as defined in app/config/database.php
}

      

Then your code

public function devUserCreateTest()
{
    DB::beginTransaction();
    DB::connection('some_connection')->beginTransaction(); // same as the one used in model ChildUser

    try {

        $childUser  = new ChildUser; // Exists in database B
        $parentUser = new User; // Exists in database A
        $parentUser->setEmailAttribute('mike@example.com');
        $parentUser->save();
        $childUser->parent_user_id = $parentUser->id;
        $message = sprintf('Parent user id: %s', serialize($childUser->id));
        $childUser->save();
        $message = sprintf('Core user id: %s | hta user id: %s', serialize($parentUser->id), serialize($childUser->id));
        throw new Exception('Testing....');
        DB::commit();
    } catch (Exception $e) {
        Log::warning(sprintf('Exception: %s', $e->getMessage()));

        DB::rollback();
        DB::connection('some_connection')->rollback();
    }
    return $this->buildResponse(array('message' => $message));
}

      

+2


source







All Articles