laravelのコントローラーで、エラーが発生していないのにデータベースへの登録ができない状況が発生しました。非常に単純なミスなので、同じ過ちをしないように備忘録として残しておきます。
■原因
DB::beginTransaction();を行った後、try{}内でsave()を行った後、
DB::commit();をしていなかったから。
■諸現象
実際にどのような状況になるのかというと、
①Laravel.logにはエラーは吐かれない→正常
②Laravel.logにSQL文を表示させると、きちんとinsert()がされていることを確認できる→正常
③axios通信の場合、201createdがresponse.statusとして返却される→正常
④axios通信の場合、response.dataとして、登録したデータを取得することができる→正常
⑤データベースのidが飛ばされる
例:id=1のデータ→データベースに登録済
id=2のデータ→上記原因により、データベースに登録されない現象が発生
id=3のデータ→データベースに正常に登録できた
例の場合は、データベースを確認するとid=1、id=3のデータしか確認できず、
idが飛ばされる現象が発生→おかしい
このような状況となる。
Laravelについての不勉強とエラーが発生しないことにより、原因の特定が遅れた。
■原因特定方法
①データの代入に問題(変数名が違う、型が違うなど)があるのか?
$user = new User();
DB::beginTransaction();
try{
$user->name = $request->name;
//age以外では、データベースへの登録ができるかどうか確認する
//$user->age = $request->age;
$user->place = $request->place;
$user->save();
} catch (\Exception $exception){
DB::rollback();
throw $exception;
}
変数のミス、代入時のミスはあるあるなので、まずは一つずつ間違っていないか確認。
上記のように、一つずつ代入する値を入れ替えていき、問題個所を特定しようとした。
しかし、どのパターンで試してもデータベースへの登録ができず、変数の代入に問題があるわけではないことが判明する。
②try catchを外してデータベースの登録ができるか確認
$user = new User();
//例外処理を行わず、そのままデータベースへ登録する
//DB::beginTransaction();
//try{
$user->name = $request->name;
$user->age = $request->age;
$user->place = $request->place;
$user->save();
//} catch (\Exception $exception){
// DB::rollback();
// throw $exception;
// }
②を行うと、データベースへの登録ができたため、トランザクション処理に原因があると判明し、原因特定に至る
③トランザクション処理を修正し、正常にデータベースへの登録ができることを確認
$user = new User();
DB::beginTransaction();
try{
$user->name = $request->name;
$user->age = $request->age;
$user->place = $request->place;
$user->save();
//DB::commit();を書き忘れていたため、加筆
DB::commit();
} catch (\Exception $exception){
DB::rollback();
throw $exception;
}