このページの2つのバージョン間の差分を表示します。
| 両方とも前のリビジョン 前のリビジョン 次のリビジョン | 前のリビジョン | ||
|
apricot:usage:ja:controller [2020/08/26 20:28] y2sunlight [トランザクション] |
apricot:usage:ja:controller [2020/09/03 13:46] (現在) y2sunlight [Apricot コントローラ] |
||
|---|---|---|---|
| 行 1: | 行 1: | ||
| - | > 編集中 | ||
| - | |||
| - | ---- | ||
| - | |||
| ====== Apricot コントローラ ====== | ====== Apricot コントローラ ====== | ||
| --- // | --- // | ||
| 行 21: | 行 17: | ||
| * [[apricot: | * [[apricot: | ||
| * [[apricot: | * [[apricot: | ||
| + | * [[apricot: | ||
| * [[apricot: | * [[apricot: | ||
| 行 360: | 行 357: | ||
| ===== トランザクション ===== | ===== トランザクション ===== | ||
| - | Apricotでは、コントローラのアクションをラップする形でトランザクションをアクションに適用できます。Apricotは、トランザクションの適用されたアクションを呼び出す前にトランザクションを開始し、アクションが正常に終了するとそのトランザクションをコミットします。アクションが例外をスローした場合、Apricotは、それをキャッチしてエラーログを出力して、アクションの代わりに前画面に戻るリダイレクトレスポンスをクライアントに返します。これらの処理は全てApricotのフレームワーク内で行われるのでアクションのコーディングを最小限にすることができます。 | + | Apricotでは、コントローラのアクションをラップする形で、アクションにトランザクションを適用することができます。Apricotは、トランザクションの適用されたアクションを呼び出す前にトランザクションを開始し、アクションが正常に終了するとそのトランザクションをコミットします。アクションが |
| \\ | \\ | ||
| ==== トランザクションの適用 ==== | ==== トランザクションの適用 ==== | ||
| + | |||
| + | アクションにトランザクションを適用するには、以下のように、コンストラクターの中で、コントローラの '' | ||
| <code php> | <code php> | ||
| class FooController extends Controller | class FooController extends Controller | ||
| { | { | ||
| - | public function __construct() | + | public function __construct(User $user) |
| { | { | ||
| - | // インターセプターの登録 | + | // トランザクションの適用 |
| - | $this->intercept('action', | + | $this->transactional('insert',' |
| - | { | + | |
| - | $inputs = Input::all(); | + | |
| - | // バリデーション処理 | + | |
| - | | + | |
| } | } | ||
| - | ... | + | |
| } | } | ||
| </ | </ | ||
| - | + | この例では、insert、updateそしてdeteleの各アクションにトランザクションを適用しています。このように、'' | |
| - | + | ||
| - | ユーザ登録画面にトランザクションの機能を追加します。トランザクションを作るか否かはアクション毎に設定できるようにします。また、トランザクション機能を追加することによりアクションでスローされる ApplicationException をキャッチして(エラー画面に遷移することなく)入力画面でエラーメッセージを表示できるようになります。アクションでスローされるApplicationException には以下のものがあります。 | + | |
| - | + | ||
| - | * 楽観的ロック例外(OptimissticLockException) | + | |
| - | * 対象レコードが存在しない(レコード更新時および削除時) | + | |
| - | * その他のアクションで発生する'' | + | |
| - | + | ||
| - | 通常、トランザクションは更新系の処理で設定するするので、参照系で発生した全ての例外は集約エラーハンドラで処理されエラー画面が表示されます。この状況を避けたい場合は、次の何れかの選択になるでしょう。 | + | |
| - | + | ||
| - | * 参照系アクションもトランザクションを設定する | + | |
| - | * アクション内のcatchブロックでエラーメッセージ付きの入力画面をレンダリングする | + | |
| \\ | \\ | ||
| - | ==== 使用例:ユーザコントローラ ==== | + | ==== トランザクションの処理 |
| - | アクションのトランザクション処理を有効にしたい場合は、コントローラのコンストラクタの中でControllerクラスのtransactional()メソッドを使って、以下のようにします。 | + | 以下は、ユーザコントローラの |
| - | + | ||
| - | * **transactional( ' | + | |
| - | + | ||
| - | {{fa> | + | |
| - | <code php UserController.php> | + | |
| - | <?php | + | |
| - | namespace App\Controllers; | + | |
| - | + | ||
| - | use App\Exceptions\ApplicationException; | + | |
| - | use App\Foundation\Controller; | + | |
| - | use App\Models\User; | + | |
| - | use Core\Input; | + | |
| + | <code php> | ||
| /** | /** | ||
| - | | + | |
| + | * | ||
| + | * @param int $id | ||
| + | * @return \Apricot\Foundation\Response | ||
| */ | */ | ||
| - | class UserController extends Controller | + | public function update(int $id) |
| { | { | ||
| - | | + | |
| - | | + | |
| - | * ユーザコントローラの生成 | + | |
| - | */ | + | |
| - | public function __construct() | + | |
| { | { | ||
| - | | + | $this-> |
| - | | + | } |
| - | + | | |
| - | // トランザクションアクション登録 | + | { |
| - | $this-> | + | |
| + | } | ||
| + | catch(\Exception $e) | ||
| + | { | ||
| + | throw new ApplicationException(__('messages.error.db.update' | ||
| } | } | ||
| - | ... | + | |
| + | return redirect(route(" | ||
| } | } | ||
| </ | </ | ||
| - | * transactional()を使って3つのアクション( '' | + | この例では、ユーザモデル( < |
| + | |||
| + | アクションがしなければならないことは、モデルの例外を捕捉して、ApplicationException をスローすることだけです。フレームワークは ApplicationException またはそれを親に持つ例外のみを捕捉します。それ以外の例外は、集約エラーハンドラーによって補足されシステムエラーになります。即ち、フレームワークは、ApplicationException のみ前画面に戻すリダイレクトレスポンスを生成します。 | ||
| + | |||
| + | モデルは次の場合に ApplicationException をスローします: | ||
| + | |||
| + | * 楽観的ロック例外が発生した場合( '' | ||
| + | * 対象レコードが存在しない場合(レコード更新時および削除時) | ||
| + | |||
| + | アクションでは、これ以外の例外が発生した場合は、パースエラーなどの | ||
| + | |||
| + | === クエリーの例外処理 === | ||
| + | |||
| + | 通常、トランザクションは更新系の処理で設定するするので、クエリーで発生した全ての例外は集約エラーハンドラで処理されエラー画面が表示されます。この状況を避けたい場合は、次の何れかの選択になるでしょう。 | ||
| + | |||
| + | * クエリーのアクションにもトランザクションを設定する | ||
| + | * アクション内のcatchブロックでエラーメッセージ付きの入力ページをレンダリングする | ||
| \\ | \\ | ||