第10章
第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
  1. 「TODO保存+ログ保存」を1セットにすると書く
  2. 2つ目が失敗したら1つ目も消える理由を説明する