# バッチ設計書 3-ryTask.ryMultipleParams

## 概要

本ドキュメントは、RuoYiシステムにおける定時タスク「ryTask.ryMultipleParams」（システムデフォルト・多参）のバッチ設計書である。Quartzスケジューラを利用した複数型パラメータを受け取る定時タスク実行処理について記述する。

### 本バッチの処理概要

本バッチは、システムの定時タスク機能において複数の異なる型のパラメータを渡す機能の動作確認を目的としたテスト用バッチである。String、Boolean、Long、Double、Integerの5種類の型パラメータを受け取り、コンソールにそれぞれの値を含むメッセージを出力する。

**業務上の目的・背景**：本バッチは、RuoYiシステムのQuartzベースの定時タスクスケジューリング機能において、複数の異なるデータ型パラメータを同時に扱う機能が正常に動作することを検証するためのテスト用タスクとして提供されている。JobInvokeUtilによる型推論機能（文字列はクォート、Booleanはtrue/false、LongはL接尾辞、DoubleはD接尾辞、それ以外はInteger）の動作確認に使用される。より複雑な業務タスク開発時のパラメータ設計の参考実装として機能する。

**バッチの実行タイミング**：Cron式「0/20 * * * * ?」により20秒ごとに実行されるが、デフォルトで一時停止状態に設定されている。管理画面から有効化し、必要に応じてパラメータを変更して実行できる。

**主要な処理内容**：
1. Quartzスケジューラによるジョブのトリガー
2. JobInvokeUtilによるinvokeTarget文字列のパース（Bean名、メソッド名、複数パラメータの抽出）
3. 各パラメータの型判定と変換（String, Boolean, Long, Double, Integer）
4. RyTaskクラスのryMultipleParamsメソッドの実行
5. 全パラメータ値を含むメッセージのコンソール出力
6. 実行ログのデータベースへの記録

**前後の処理との関連**：本バッチは単独で動作するテスト用タスクであり、他のバッチとの依存関係はない。ryTask.ryParamsの発展形として、複数型パラメータ処理の検証に使用される。

**影響範囲**：本バッチの実行により、sys_job_logテーブルに実行ログが追加される。システムのコンソール（標準出力）に複数パラメータ値を含むメッセージが出力される。

## バッチ種別

テスト・動作確認用タスク

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 20秒毎（デフォルト停止状態） |
| 実行時刻 | 毎分0秒、20秒、40秒 |
| 実行曜日 | 毎日 |
| 実行日 | 毎日 |
| トリガー | Cron（0/20 * * * * ?） |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| Quartzスケジューラ起動 | Spring Bootアプリケーション起動時にスケジューラが初期化されていること |
| タスク状態が正常 | sys_jobテーブルのstatus列が'0'（正常）であること |
| ryTaskビーン登録 | RyTaskクラスがSpringコンテナにBean登録されていること |
| invokeTarget設定 | 5つのパラメータを含むinvokeTarget文字列が正しく設定されていること |

### 実行可否判定

- sys_jobテーブルのstatus='0'（正常）の場合のみ実行される
- concurrent='1'（並発禁止）のため、前回実行が完了していない場合は新規実行されない
- invokeTargetのパラメータ部分のパースに失敗した場合、例外が発生して処理中断
- パラメータの型がメソッドシグネチャと一致しない場合、NoSuchMethodException発生

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| s | String | Yes | 'ry' | 文字列パラメータ |
| b | Boolean | Yes | true | ブール値パラメータ |
| l | Long | Yes | 2000L | 長整数パラメータ |
| d | Double | Yes | 316.50D | 浮動小数点パラメータ |
| i | Integer | Yes | 100 | 整数パラメータ |

### パラメータの指定方法と型判定ルール

invokeTarget文字列内でパラメータを指定する：

```
ryTask.ryMultipleParams('ry', true, 2000L, 316.50D, 100)
```

**型判定ルール（JobInvokeUtil#getMethodParams）**：

| 型 | 判定条件 | 例 |
|-----|---------|-----|
| String | `'`または`"`で開始する | `'ry'`, `"hello"` |
| Boolean | `true`または`false`（大文字小文字無視） | `true`, `false`, `TRUE` |
| Long | `L`で終了する | `2000L`, `100L` |
| Double | `D`で終了する | `316.50D`, `3.14D` |
| Integer | 上記以外の数値 | `100`, `42` |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| sys_job | DB | タスク定義情報（invoke_target、cron_expression等） |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| sys_job_log | DB | タスク実行ログ |
| 標準出力 | コンソール | パラメータ値を含むメッセージ |

### 出力メッセージ形式

```
执行多参方法： 字符串类型{s}，布尔类型{b}，长整型{l}，浮点型{d}，整形{i}
```

デフォルト設定での出力例：
```
执行多参方法： 字符串类型ry，布尔类型true，长整型2000，浮点型316.5，整形100
```

### 出力ファイル仕様

本バッチはファイル出力を行わない。

## 処理フロー

### 処理シーケンス

```
1. Quartzトリガー発火
   └─ Cron式に基づきQuartzがジョブをトリガー
2. AbstractQuartzJob#execute実行
   └─ JobExecutionContextからSysJob情報を取得
3. before処理
   └─ 開始時刻をThreadLocalに記録
4. doExecute実行（QuartzDisallowConcurrentExecution）
   └─ JobInvokeUtil#invokeMethodを呼び出し
5. invokeTargetパース
   └─ beanName: ryTask, methodName: ryMultipleParams を抽出
6. パラメータ文字列分割
   └─ カンマ区切りで分割（クォート内のカンマは除外）
7. 各パラメータの型判定と変換
   └─ 'ry' → String("ry")
   └─ true → Boolean(true)
   └─ 2000L → Long(2000)
   └─ 316.50D → Double(316.50)
   └─ 100 → Integer(100)
8. Beanの取得
   └─ SpringUtils.getBean("ryTask")でRyTaskインスタンス取得
9. メソッド呼び出し
   └─ リフレクションでryMultipleParams(String, Boolean, Long, Double, Integer)を特定
10. メソッド実行
    └─ RyTask#ryMultipleParams("ry", true, 2000L, 316.50D, 100)を実行
11. メッセージ出力
    └─ System.out.println(StringUtils.format(...))
12. after処理
    └─ 終了時刻を記録、実行時間を計算
13. ログ記録
    └─ sys_job_logテーブルにINSERT
```

### フローチャート

```mermaid
flowchart TD
    A[Quartzトリガー発火] --> B[AbstractQuartzJob#execute]
    B --> C[before: 開始時刻記録]
    C --> D[doExecute呼び出し]
    D --> E[JobInvokeUtil#invokeMethod]
    E --> F[getBeanName: ryTask抽出]
    F --> G[getMethodName: ryMultipleParams抽出]
    G --> H[getMethodParams: パラメータ文字列取得]
    H --> I[カンマで分割]
    I --> J1[パラメータ1: String型判定]
    I --> J2[パラメータ2: Boolean型判定]
    I --> J3[パラメータ3: Long型判定]
    I --> J4[パラメータ4: Double型判定]
    I --> J5[パラメータ5: Integer型判定]
    J1 --> K[型配列・値配列作成]
    J2 --> K
    J3 --> K
    J4 --> K
    J5 --> K
    K --> L[SpringUtils.getBean取得]
    L --> M[getMethod: メソッド取得]
    M --> N[method.invoke: メソッド実行]
    N --> O[ryMultipleParams実行]
    O --> P[StringUtils.formatでメッセージ作成]
    P --> Q[コンソール出力]
    Q --> R[after: 終了時刻記録]
    R --> S{例外発生?}
    S -->|No| T[status=SUCCESS]
    S -->|Yes| U[status=FAIL, 例外情報記録]
    T --> V[sys_job_logにINSERT]
    U --> V
    V --> W[処理終了]
```

## データベース操作仕様

### 操作別データベース影響一覧

| 処理 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| ログ記録 | sys_job_log | INSERT | タスク実行結果をログテーブルに記録 |

### テーブル別操作詳細

#### sys_job_log

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | job_name | SysJob#jobNameの値（システムデフォルト（多参）） | タスク名称 |
| INSERT | job_group | SysJob#jobGroupの値（DEFAULT） | タスクグループ |
| INSERT | invoke_target | ryTask.ryMultipleParams('ry', true, 2000L, 316.50D, 100) | 呼び出し対象文字列 |
| INSERT | job_message | "{job_name} 总共耗时：{n}毫秒" | 実行結果メッセージ |
| INSERT | status | '0'（成功）または'1'（失敗） | 実行状態 |
| INSERT | exception_info | 例外発生時のスタックトレース（最大2000文字） | エラー時のみ |
| INSERT | start_time | 実行開始日時 | before処理で記録 |
| INSERT | end_time | 実行終了日時 | after処理で記録 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | NoSuchMethodException | ryMultipleParams(String,Boolean,Long,Double,Integer)メソッドが存在しない、またはシグネチャ不一致 | RyTaskクラスの実装とinvokeTargetのパラメータ順序・型を確認 |
| - | IllegalAccessException | メソッドへのアクセス権限がない | メソッドのアクセス修飾子を確認 |
| - | IllegalArgumentException | パラメータの型が不一致 | invokeTargetの記述形式と型接尾辞を確認 |
| - | InvocationTargetException | メソッド実行中に例外発生 | メソッド内の実装を確認 |
| - | BeanNotFoundException | ryTaskビーンが見つからない | @Component設定を確認 |
| - | NumberFormatException | 数値パラメータのパースに失敗 | Long/Double/Integerの値が正しい形式か確認 |
| - | StringIndexOutOfBoundsException | パラメータのクォート記述が不正 | invokeTargetの引用符を確認 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし（自動リトライなし） |
| リトライ間隔 | - |
| リトライ対象エラー | - |

### 障害時対応

1. sys_job_logテーブルでstatus='1'のレコードを確認
2. exception_infoカラムからエラー内容を特定
3. invokeTargetの形式が正しいか確認（パラメータ数、型接尾辞、クォート）
4. パラメータの順序がメソッドシグネチャと一致しているか確認
5. 必要に応じてタスクを一時停止（status='1'に更新）
6. 管理画面から手動で「即時実行」して動作確認

## トランザクション仕様

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | ログ記録処理のみ |
| コミットタイミング | ログINSERT完了時 |
| ロールバック条件 | ログ記録中の例外発生時 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | 1件/実行 |
| 目標処理時間 | 100ms以内 |
| メモリ使用量上限 | 特に制限なし（軽量処理） |

## 排他制御

- concurrent='1'（並発禁止）により、同一ジョブの並発実行は禁止
- @DisallowConcurrentExecutionアノテーションにより、Quartzレベルで排他制御
- 前回実行が完了するまで次回実行はスキップされる

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 開始ログ | なし | 標準では出力なし |
| 進捗ログ | なし | 標準では出力なし |
| 終了ログ | バッチ終了時 | DB（sys_job_log）に記録 |
| エラーログ | エラー発生時 | "任务执行异常 - ："+ スタックトレース |
| 業務ログ | メソッド実行時 | "执行多参方法：..."（標準出力） |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| 処理時間 | 設定なし | - |
| エラー件数 | 設定なし | - |

※本バッチはテスト用のため、監視・アラート設定は行われていない

## 備考

- 本バッチはRuoYiフレームワークが提供するサンプル定時タスクであり、複数型パラメータ渡し機能の検証用
- デフォルトで一時停止状態（status='1'）に設定されており、意図的に有効化しない限り実行されない
- パラメータはinvokeTarget内に直接記述する形式（管理画面から変更可能）
- invokeTargetの書式：`ryTask.ryMultipleParams('文字列', true/false, 数値L, 数値D, 数値)`
- JobInvokeUtil#getMethodParamsでの型判定ロジック：
  1. `'`または`"`で開始 → String型
  2. `true`または`false`（大文字小文字無視） → Boolean型
  3. `L`で終了 → Long型
  4. `D`で終了 → Double型
  5. それ以外 → Integer型
- パラメータの区切り文字はカンマだが、クォート内のカンマは区切りとして扱わない
  - 正規表現：`",(?=([^\"']*[\"'][^\"']*[\"'])*[^\"']*$)"`
