从类中实例化eloquant时,事务不起作用

时间:2017-03-13 13:45:25

标签: laravel laravel-5 eloquent laravel-eloquent

我尝试使用OUTSIDE laravel进行交易。当我在我的索引文件中包含db实例化时,它可以正常工作:

use Illuminate\Database\Capsule\Manager as Db;



$db = new Db;

$db->addConnection( [
    'driver'    => Settings::DATABASE_DRIVER,
    'host'      => Settings::DATABASE_HOST,
    'database'  => Settings::DATABASE_NAME,
    'username'  => Settings::DATABASE_USERNAME,
    'password'  => Settings::DATABASE_PASSWORD,
    'charset'   => 'utf8',
    'collation' => 'utf8_unicode_ci',
    'prefix'    => ''
] );

# Make this Capsule instance available globally via static methods... (optional)
$db->setAsGlobal();

我可以在其他地方使用这样的代码:

Db::connection()->beginTransaction();

# Create blog post in the database and return its id
$blogPostRecordId = ( new BlogDbModel() )->create( $_POST );
Db::connection()-> rollBack();

它将正确工作和回滚:在db中没有创建行。

但是,如果我从一个类中获取数据库的实例,它就不会工作:

class DbSql
{

    /**
     * Use the eloquent query builder and orm. Bypass PDO interface.
     * @return Capsule
     */
    public function db()
    {
        $capsule = new Capsule;

        $capsule->addConnection( [
            'driver'    => Settings::DATABASE_DRIVER,
            'host'      => Settings::DATABASE_HOST,
            'database'  => Settings::DATABASE_NAME,
            'username'  => Settings::DATABASE_USERNAME,
            'password'  => Settings::DATABASE_PASSWORD,
            'charset'   => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix'    => ''
        ] );

        # Make this Capsule instance available globally via static methods... (optional)
        $capsule->setAsGlobal();

        // Setup the Eloquent ORM... (optional; unless you've used setEventDispatcher())
        //$capsule->bootEloquent();


        return $capsule;
    }
}

然后使用

( new DbSql() )->db()->getConnection()->beginTransaction();

# Create blog post in the database and return its id
$blogPostRecordId = ( new BlogDbModel() )->create( $_POST );
( new DbSql() )->db()->getConnection()->rollBack();

它只是赢了工作而且交易被忽略了。为什么从类实例化中获取db实例会导致进程失败?我更愿意根据需要使用实例。

1 个答案:

答案 0 :(得分:0)

解决方案:在需要事务的地方,db实例必须完全相同:

$dbInstance = ( new DbSql() )->db();

然后在要遵循事务的地方使用$ dbInstance:

$dbInstance->connection()->beginTransaction();

以及任何db eloquent操作。所以根据需要传递$ dbInstance。好处是它可以在你的代码中的任何地方:在你的模型,控制器....

然后完成:

 $dbInstance->connection()->commit();

如果系统无法到达最后一行,则不会向db提交任何内容。