Laravel 中的交易
在某些情况下,我们需要进行一系列连续的操作,必须全部顺利完成,不能半途而废。
一个常见的示例是创建用户,其中还必须分配角色并发送注册电子邮件。
为了处理这些类型的情况,需要使用事务。下面的方法创建用户、分配角色,然后通过 sendemail() 方法发送电子邮件。此方法接收电子邮件作为参数并相应地发送它。
use illuminatesupportacadesdb;public function save(array $data){ try { $user = user::create($data); $user->syncroles([$data['role']]); $this->sendemail([ 'email' => $data['email'], ]); return $user; } catch (exception $e) { throw new badrequestexception("error al guardar nuevo usuario"); }}
我们必须应用3种方法:
在我们剩下的之前的代码中实现交易:
use illuminatesupportacadesdb;public function save(array $data){ // iniciar la transacción db::begintransaction(); try { $user = user::create($data); $user->syncroles([$data['role']]); $this->sendemail([ 'email' => $data['email'], ]); // confirmo la transacción db::commit(); return $user; } catch (exception $e) { // si falla hago rollback db::rollback(); throw new badrequestexception("error al guardar nuevo usuario"); } }
这样我们就可以确保这组操作完全执行或根本不执行。
laravel 还提供了另一种更具体的 db 门面事务方法。在这种情况下,提交和回滚是自动完成的。当操作次数很少或者在执行回滚之前不需要额外操作时建议这样做
DB::transaction(function () use($data){ $user = User::create($data); $user->syncRoles([$data['role']]); $this->sendEmail([ 'email' => $data['email'], ]); return $user;});
重要:数据库引擎注意事项
并非所有存储引擎都支持事务。 innodb是一个确实支持事务的引擎,而myisam则不支持。确保您的数据库表使用支持事务的引擎才能正常运行,这一点至关重要。