繁体   English   中英

Laravel Eloquent ORM 交易

[英]Laravel Eloquent ORM Transactions

The Eloquent ORM is quite nice, though I'm wondering if there is an easy way to setup MySQL transactions using innoDB in the same fashion as PDO, or if I would have to extend the ORM to make this possible?

你可以这样做:

DB::transaction(function() {
      //
});

闭包中的所有内容都在事务中执行。 如果发生异常,它将自动回滚。

如果您不喜欢匿名函数:

try {
    DB::connection()->pdo->beginTransaction();
    // database queries here
    DB::connection()->pdo->commit();
} catch (\PDOException $e) {
    // Woopsy
    DB::connection()->pdo->rollBack();
}

更新 :对于laravel 4, pdo对象不再公开,因此:

try {
    DB::beginTransaction();
    // database queries here
    DB::commit();
} catch (\PDOException $e) {
    // Woopsy
    DB::rollBack();
}

如果您想使用口才,也可以使用

这只是我的项目中的示例代码

        /* 
         * Saving Question
         */
        $question = new Question;
        $questionCategory = new QuestionCategory;

        /*
         * Insert new record for question
         */
        $question->title = $title;
        $question->user_id = Auth::user()->user_id;
        $question->description = $description;
        $question->time_post = date('Y-m-d H:i:s');

        if(Input::has('expiredtime'))
            $question->expired_time = Input::get('expiredtime');

        $questionCategory->category_id = $category;
        $questionCategory->time_added = date('Y-m-d H:i:s');

        DB::transaction(function() use ($question, $questionCategory) {

            $question->save();

            /*
             * insert new record for question category
             */
            $questionCategory->question_id = $question->id;
            $questionCategory->save();
        });

如果您想避免闭包,并乐于使用外墙,则可以使事情保持整洁:

try {
    \DB::beginTransaction();

    $user = \Auth::user();
    $user->fill($request->all());
    $user->push();

    \DB::commit();

} catch (Throwable $e) {
    \DB::rollback();
}

如果有任何语句失败,则提交将永远不会执行,并且事务也不会处理。

我确定您不是要寻找封闭解决方案,请尝试使用此解决方案以获取更紧凑的解决方案

 try{
    DB::beginTransaction();

    /*
     * Your DB code
     * */

    DB::commit();
}catch(\Exception $e){
    DB::rollback();
}

由于某种原因,在任何地方都很难找到该信息,所以我决定将其发布在这里,因为我的问题虽然与Eloquent交易有关,但确实在改变它。

读完这个 stackoverflow的答案后,我意识到我的数据库表正在使用MyISAM而不是InnoDB。

为了使事务能够在Laravel上(或其他任何地方)运行,需要将表设置为使用InnoDB

为什么?

引用MySQL Transactions和Atomic Operations文档( 此处 ):

MySQL服务器(版本3.23-max和所有版本4.0及更高版本)支持使用InnoDB和BDB事务存储引擎的事务。 InnoDB提供完全的ACID合规性。 请参阅第14章,存储引擎。 有关InnoDB与标准SQL在事务错误处理方面的区别的信息,请参见第14.2.11节“ InnoDB错误处理”。

MySQL Server中的其他非事务性存储引擎(例如MyISAM)遵循称为“原子操作”的数据完整性的另一范式。在事务方面,MyISAM表始终始终以autocommit = 1模式运行。 原子操作通常提供可比的完整性和更高的性能。

因为MySQL Server支持这两种范例,所以您可以决定是通过原子操作的速度还是使用事务功能来最好地为应用程序提供服务。 可以按表进行选择。

如果发生任何异常,则事务将自动回滚。

Laravel基本交易格式

    try{
    DB::beginTransaction();

    /* 
    * SQL operation one 
    * SQL operation two
    ..................     
    ..................     
    * SQL operation n */


    DB::commit();
   /* Transaction successful. */
}catch(\Exception $e){       

    DB::rollback();
    /* Transaction failed. */
}

最好和明确的方法:

DB::beginTransaction();

try {
    DB::insert(...);
    DB::insert(...);
    DB::insert(...);

    DB::commit();
    // all good
} catch (\Exception $e) {
    DB::rollback();
    // something went wrong
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM