DataBaseの絡むプログラムを実装するには、整合性の保持のために、エラーが出たら処理前の状態に戻す(ロールバックする)必要性があります。
今回は、これをCakePHPで実装する方法を解説します。
以下のように簡単に実装できます。
実装例
以下、コードの例です。
//src/Controller/SamplesController.php
<?php
use Cake\Datasource\ConnectionManager;
class SamplesController extends AppController
{
//トランザクション開始
$connection = ConnectionManager::get('default');
$connection->begin();
try {
//処理・・・
//エラーが発生していなければ処理を実行
$connection->commit();
}catch(\Exception $e) {
//例外処理・・・
//ロールバック
$connection->rollback();
}
}
try,catchと組み合わせて、異常時にはrollbackすることで簡単に実装できます。
DBへのデータ保存を行う際には、不整合が生じないように必ず実装するようにしましょう。
保存処理について ※2023年5月4日追記
save()だとrollback処理が走らない・・・。
保存処理には、save()を使うのが一般的ですが、上記のようなトランザクション処理には不適切です。
これは、save()は失敗時に単にfalseを返してしまうためです。
失敗時にはExceptionをthrowしてもらわないと、rollback処理が走らないので、先述のコードが無駄になってしまいます。
saveOrFail()を使おう
saveOrFail()を使えば、保存に失敗した際にはExceptionがthrowされるので、ロールバックが走ります。
先述のコードのトランザクション部分に当てはめると下記のようになります。
//トランザクション開始
$connection = ConnectionManager::get('default');
$connection->begin();
try {
//処理・・・
//下記のsave()だと、保存に失敗してもrollbackが走らない。
//$samplesTable->save($data);
//saveOrFail()を使う。
$samplesTable->saveOrFail($data);
//エラーが発生していなければ処理を実行
$connection->commit();
}catch(\Exception $e) {
//例外処理・・・
//ロールバック
$connection->rollback();
}
コメント