【问题标题】:Laravel 4.2 - Transaction rollback issue with multiple databasesLaravel 4.2 - 多个数据库的事务回滚问题
【发布时间】:2015-08-27 19:06:24
【问题描述】:

我在回滚涉及来自多个数据库的表的事务时遇到问题。主表回滚的行为符合预期,但子行仍然存在,现在是孤立的。

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));
}

看起来这样可行:

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));
}

【问题讨论】:

    标签: php laravel pdo transactions


    【解决方案1】:

    您还必须在数据库 B 上设置一个事务。

    由于您没有发布ChildUser 代码,因此这里是一个示例:

    app/models/ChildUser.php:

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

    然后是你的代码

    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));
    }
    

    【讨论】:

    • 感谢您的响应...看来您是正确的,我必须本地化两个单独的数据库对象,然后初始化,并针对每个连接提交/回滚。
    • 之后不需要提交吗?
    猜你喜欢
    • 1970-01-01
    • 2020-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多