📘 Vol.10.6：Service層の設計方針と例外処理戦略   〜複数DAO呼び出し・トランザクション・例外管理の責務を明確に〜

## ✅ この回で学べること

- Service層の役割と設計のポイント  
- DAOとServiceの責務の分離  
- トランザクション管理の実装例  
- 例外処理の設計とベストプラクティス  

---

## 🧩 Service層の役割とは？

Service層は、「ビジネスロジックを統合」するための層です。  
主な責務は以下の通り：

| 役割 | 内容 |
|------|------|
| 複数DAOの統合 | 1つの業務処理に複数テーブルの更新が必要なときにまとめて呼び出す |
| トランザクション制御 | 成功時のコミット／失敗時のロールバックなど |
| 例外管理 | DAO層のSQLExceptionなどをまとめて扱い、アプリ層に適した例外へ変換 |

---

## ✅ シンプルな構成図

```plaintext
Controller（Action）
    ↓ 呼び出し
Service（業務ロジック・トランザクション制御）
    ↓ 呼び出し
DAO（DBアクセス）
```

---

### 📌 実装例：Service層でのトランザクション管理

### UserService.java（複数DAO＋トランザクション制御）
```java
public class UserService {
    private UserDao userDao;
    private UserRoleDao userRoleDao;
    private DataSource dataSource;

    public UserService(UserDao userDao, UserRoleDao userRoleDao, DataSource dataSource) {
        this.userDao = userDao;
        this.userRoleDao = userRoleDao;
        this.dataSource = dataSource;
    }

    public void registerUser(User user, String role) throws ServiceException {
        Connection conn = null;
        try {
            conn = dataSource.getConnection();
            conn.setAutoCommit(false); // トランザクション開始

            userDao.insert(conn, user);
            userRoleDao.assignRole(conn, user.getUserId(), role);

            conn.commit(); // 成功時コミット
        } catch (SQLException e) {
            if (conn != null) {
                try {
                    conn.rollback(); // エラー時ロールバック
                } catch (SQLException ex) {
                    // ロールバック失敗ログ
                }
            }
            throw new ServiceException("ユーザー登録失敗", e);
        } finally {
            if (conn != null) {
                try {
                    conn.setAutoCommit(true); // 元に戻す
                    conn.close();
                } catch (SQLException ex) {
                    // ログ記録など
                }
            }
        }
    }
}

```

---

### UserDaoImpl.java（Connectionは引数で受け取る）

```java
public class UserDaoImpl implements UserDao {
    public void insert(Connection conn, User user) throws SQLException {
        String sql = "INSERT INTO users (user_id, username, email) VALUES (?, ?, ?)";
        try (PreparedStatement stmt = conn.prepareStatement(sql)) {
            stmt.setInt(1, user.getUserId());
            stmt.setString(2, user.getUsername());
            stmt.setString(3, user.getEmail());
            stmt.executeUpdate();
        }
    }
}
```

---

### ✅ Service層を設けるメリット

- 業務ロジックを集約できる（Actionに書かない）

- トランザクション開始・終了の制御を一元化できる

- エラーハンドリング戦略を統一できる（例：ServiceExceptionにラップ）

---

### ☑ よくあるパターン

| パターン     | 使用例                                |
| -------- | ---------------------------------- |
| 単一DAO処理  | Service層を設けず、Action → DAO直呼びでもOK   |
| 複数DAO使用  | Service層でまとめて処理・トランザクション制御が必要      |
| ロジック分岐あり | DAOの呼び出し順序や分岐ロジックがある場合はService層で制御 |


---

### 💡 例外処理設計のTips

- DAO層ではSQLExceptionなど「技術例外」をスロー

- Service層では独自例外（例：ServiceException）でラップ

- Action層ではServiceExceptionをキャッチして画面遷移制御やログ出力

---


### ✅ 今回のまとめ

| 項目          | ポイント                                 |
| ----------- | ------------------------------------ |
| Service層の目的 | DAOの統合呼び出し・トランザクション・例外管理             |
| トランザクション制御  | Service層でConnection開始→DAOに渡す方式が王道    |
| 例外管理        | DAOでSQLException → Service層で独自例外にラップ |
| 設計方針        | 単純な処理ならDAOだけ。複雑な処理はService層を設ける      |


---

📘 次回予告：「Vol.10.7：Service層×JUnitテストの基本とパターン」を予定しています！

---

### ✨ シリーズまとめ（Vol.10.x バリデーション編）

- [✅ Vol.10.0：DAO / DTO / JavaBeansとは？ ― データ層設計の全体像と役割分担 ―](https://qiita.com/drafts/19c1d526df28240e0cb1/edit)

- [✅ Vol.10.1：DTO設計のベストプラクティス（命名規則・フィールド設計](https://qiita.com/juehara-crypto/items/1b0ad616095f8ae134ec)

- [✅ Vol.10.2：DAOのインタフェース設計と実装パターン ](https://qiita.com/juehara-crypto/items/bcb15618440bef5931ef)

- [✅ Vol.10.3：DB接続クラスの共通化とドライバ設計](https://qiita.com/juehara-crypto/items/c3d4e8e6887d5ec8e1eb)

- [✅ Vol.10.4：Actionとの連携実装（Struts2との融合）](https://qiita.com/juehara-crypto/items/b8873de1aa9e46cd9309)

- [✅ Vol.10.5：DAO・DTOのテスト設計（JUnitやH2活用）](https://qiita.com/juehara-crypto/items/9f0914697726068b9e93)

- [✅ Vol.10.7：Service層×JUnitテストの基本とパターン](https://qiita.com/juehara-crypto/items/128fda40df3ffa0fedce)

- [✅ Vol.10.8：Service層の共通基盤化とDI対応 ](https://qiita.com/juehara-crypto/items/8e94acf2a31be15aaf94)

---