php Laravel Eloquent ORM 事务
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15105640/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Laravel Eloquent ORM Transactions
提问by wesside
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?
Eloquent ORM 非常好,但我想知道是否有一种简单的方法可以像 PDO 一样使用 innoDB 设置 MySQL 事务,或者我是否必须扩展 ORM 才能实现这一点?
回答by Laurence
You can do this:
你可以这样做:
DB::transaction(function() {
//
});
Everything inside the Closure executes within a transaction. If an exception occurs it will rollback automatically.
Closure 中的所有内容都在事务中执行。如果发生异常,它将自动回滚。
回答by Jürgen Paul
If you don't like anonymous functions:
如果你不喜欢匿名函数:
try {
DB::connection()->pdo->beginTransaction();
// database queries here
DB::connection()->pdo->commit();
} catch (\PDOException $e) {
// Woopsy
DB::connection()->pdo->rollBack();
}
Update: For laravel 4, the pdoobject isn't public anymore so:
更新:对于laravel 4,该pdo对象不再公开,因此:
try {
DB::beginTransaction();
// database queries here
DB::commit();
} catch (\PDOException $e) {
// Woopsy
DB::rollBack();
}
回答by Aditya Kresna Permana
If you want to use Eloquent, you also can use this
如果你想使用 Eloquent,你也可以使用这个
This is just sample code from my project
这只是我项目中的示例代码
/*
* 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();
});
回答by Chris
If you want to avoid closures, and happy to use facades, the following keeps things nice and clean:
如果你想避免闭包,并乐于使用门面,以下内容可以保持整洁:
try {
\DB::beginTransaction();
$user = \Auth::user();
$user->fill($request->all());
$user->push();
\DB::commit();
} catch (Throwable $e) {
\DB::rollback();
}
If any statements fail, commit will never hit, and the transaction won't process.
如果任何语句失败,提交将永远不会命中,并且事务将不会处理。
回答by imal hasaranga perera
I'm Sure you are not looking for a closure solution, try this for a more compact solution
我确定您不是在寻找封闭解决方案,试试这个以获得更紧凑的解决方案
try{
DB::beginTransaction();
/*
* Your DB code
* */
DB::commit();
}catch(\Exception $e){
DB::rollback();
}
回答by dmmd
For some reason it is quite difficult to find this information anywhere, so I decided to post it here, as my issue, while related to Eloquent transactions, was exactly changing this.
出于某种原因,很难在任何地方找到这些信息,所以我决定把它贴在这里,因为我的问题虽然与 Eloquent 交易有关,但正在改变这一点。
After reading THISstackoverflow answer, I realized my database tables were using MyISAM instead of InnoDB.
阅读完这个stackoverflow 答案后,我意识到我的数据库表使用的是 MyISAM 而不是 InnoDB。
For transactions to work on Laravel (or anywhere else as it seems), it is required that your tables are set to use InnoDB
对于在 Laravel(或其他任何地方)上工作的事务,需要将您的表设置为使用 InnoDB
Why?
为什么?
Quoting MySQL Transactions and Atomic Operationsdocs (here):
引用 MySQL事务和原子操作文档(此处):
MySQL Server (version 3.23-max and all versions 4.0 and above) supports transactions with the InnoDB and BDB transactional storage engines. InnoDB provides full ACID compliance. See Chapter 14, Storage Engines. For information about InnoDB differences from standard SQL with regard to treatment of transaction errors, see Section 14.2.11, “InnoDB Error Handling”.
The other nontransactional storage engines in MySQL Server (such as MyISAM) follow a different paradigm for data integrity called “atomic operations.” In transactional terms, MyISAM tables effectively always operate in autocommit = 1 mode. Atomic operations often offer comparable integrity with higher performance.
Because MySQL Server supports both paradigms, you can decide whether your applications are best served by the speed of atomic operations or the use of transactional features. This choice can be made on a per-table basis.
MySQL Server(版本 3.23-max 和所有版本 4.0 及更高版本)支持与 InnoDB 和 BDB 事务存储引擎的事务。InnoDB 提供完全的 ACID 合规性。请参阅第 14 章,存储引擎。有关 InnoDB 在事务错误处理方面与标准 SQL 的差异的信息,请参阅第 14.2.11 节,“InnoDB 错误处理”。
MySQL Server 中的其他非事务性存储引擎(例如 MyISAM)遵循不同的数据完整性范例,称为“原子操作”。在事务方面,MyISAM 表始终有效地在 autocommit = 1 模式下运行。原子操作通常提供可比的完整性和更高的性能。
因为 MySQL Server 支持这两种范式,您可以决定是原子操作的速度还是事务功能的使用为您的应用程序提供最佳服务。可以在每个表的基础上进行此选择。
回答by srmilon
If any exception occurs, the transaction will rollback automatically.
如果发生任何异常,事务将自动回滚。
Laravel Basic transaction format
Laravel 基本交易格式
try{
DB::beginTransaction();
/*
* SQL operation one
* SQL operation two
..................
..................
* SQL operation n */
DB::commit();
/* Transaction successful. */
}catch(\Exception $e){
DB::rollback();
/* Transaction failed. */
}

