第10章 · 初心者向け
Transaction
複数の保存を「全部成功」か「全部なかったこと」にまとめる仕組みです。
1. Transactionとは
複数のDB操作を、1セットとして扱うこと
2. なぜ必要なのか
たとえ
口座Aから下ろして口座Bに入れる途中で失敗したら、片方だけ減っては困ります。両方まとめて確定/取消が必要です。
3. BEGIN / COMMIT / ROLLBACK
BEGIN… セット開始COMMIT… 全部OKなので確定ROLLBACK… 失敗したので取り消し
4. CakePHPでTransactionを使う
おすすめは「任せきり」の書き方です。
$connection = $this->Todos->getConnection();
$connection->transactional(function () {
// ここで複数 save
// 例外が出たら自動で rollback
return true;
});
5. 複数のDB更新
$connection->transactional(function () use ($order, $items) {
$this->Orders->saveOrFail($order);
foreach ($items as $item) {
$this->OrderItems->saveOrFail($item);
}
return true;
});
saveOrFail は失敗時に例外を出すので、Transactionと相性がよいです。
6. 途中で失敗した場合
1つでも失敗 → 全部なかったことになる(ROLLBACK)
7. 例外処理との組み合わせ
try {
$connection->transactional(function () use ($todo, $log) {
$this->Todos->saveOrFail($todo);
$this->Logs->saveOrFail($log);
return true;
});
$this->Flash->success('完了');
} catch (\Throwable $e) {
$this->Flash->error('処理に失敗しました');
}
第10章 やってみよう
EXERCISE
- 「TODO保存+ログ保存」を1セットにすると書く
- 2つ目が失敗したら1つ目も消える理由を説明する