我尝试使用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实例会导致进程失败?我更愿意根据需要使用实例。
答案 0 :(得分:0)
解决方案:在需要事务的地方,db实例必须完全相同:
$dbInstance = ( new DbSql() )->db();
然后在要遵循事务的地方使用$ dbInstance:
$dbInstance->connection()->beginTransaction();
以及任何db eloquent操作。所以根据需要传递$ dbInstance。好处是它可以在你的代码中的任何地方:在你的模型,控制器....
然后完成:
$dbInstance->connection()->commit();
如果系统无法到达最后一行,则不会向db提交任何内容。