SpringBootトランザクション管理とバリデーション

今回はトランザクションとバリデーションについて記事にしました。

1. トランザクションとは？
トランザクションは、一連のデータベース操作をひとまとまりの処理として管理し、全ての操作が成功するか、または全てを元に戻す（ロールバック）仕組みを指します。これにより、データベースの整合性と信頼性が保たれます。

例: 銀行のシステムで、ある口座から別の口座へお金を移動させる処理を考えてみましょう。この処理には「Aの口座からお金を引き出す」「Bの口座にお金を入金する」という2つの操作が含まれます。この2つの操作は、片方だけが成功しても意味がありません。両方の操作が成功するか、どちらもキャンセルされるべきです。これがトランザクションの役割です。

2. Spring Bootでのトランザクション管理
Spring Bootでは、@Transactional アノテーションを使って簡単にトランザクションを管理できます。Springのトランザクション管理はデフォルトでロールバック機能をサポートしており、エラーが発生した際にデータベースの状態を自動的に元に戻します。

3. トランザクションの使い方
トランザクション管理を行うには、サービス層やリポジトリ層のメソッドに @Transactional アノテーションを付けます。

```java
import org.springframework.transaction.annotation.Transactional;
import org.springframework.stereotype.Service;

@Service
public class BankService {

    @Transactional
    public void transferMoney(Long accountA, Long accountB, Double amount) {
        // Aの口座から引き出し
        withdraw(accountA, amount);

        // Bの口座に入金
        deposit(accountB, amount);
    }

    private void withdraw(Long accountId, Double amount) {
        // 口座からお金を引き出すロジック
    }

    private void deposit(Long accountId, Double amount) {
        // 口座にお金を入金するロジック
    }
}
```
このように、@Transactional アノテーションをメソッドに付与することで、Springが自動的にトランザクションを開始し、処理が成功したらコミット、例外が発生した場合はロールバックします。

4. トランザクションの細かい制御
@Transactional アノテーションは、さらに細かく設定することができます。

読み取り専用トランザクション: 読み取り専用トランザクションを使うと、データベースへの書き込みが制限され、パフォーマンスが向上します。
```java
@Transactional(readOnly = true)
public Account getAccount(Long accountId) {
    return accountRepository.findById(accountId).orElse(null);
}

```
ロールバックの条件: デフォルトでは、チェックされていない例外（RuntimeExceptionやError）が発生するとロールバックが行われますが、@Transactional アノテーションで条件を指定できます。

```java
@Transactional(rollbackFor = Exception.class)
public void process() throws Exception {
    // 例外が発生するとロールバックされる
}
```
バリデーション
1. バリデーションとは？
バリデーションとは、データの入力値が正しいかどうかを検証するプロセスです。例えば、ユーザー登録時に「メールアドレスの形式が正しいか」「パスワードが十分に長いか」「年齢が正の整数か」などをチェックします。

Spring Bootでは、標準のJava Bean Validation（JSR-380）を使用してバリデーションを簡単に実装できます。

2. Spring Bootでのバリデーションの使い方
Spring Bootでは、エンティティクラスのフィールドにアノテーションを付与することでバリデーションを設定します。例えば、ユーザー登録フォームのデータを検証する場合、@NotNull や @Size といったアノテーションを利用します。

以下はユーザー登録時のバリデーションの例です。

```java
import javax.validation.constraints.Email;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

public class UserForm {

    @NotNull(message = "名前は必須です")
    @Size(min = 2, max = 30, message = "名前は2文字以上30文字以内で入力してください")
    private String name;

    @NotNull(message = "メールアドレスは必須です")
    @Email(message = "有効なメールアドレスを入力してください")
    private String email;

    @NotNull(message = "パスワードは必須です")
    @Size(min = 6, message = "パスワードは6文字以上で入力してください")
    private String password;

    // getter と setter
}
```

3. コントローラでのバリデーション
フォームデータのバリデーションは、コントローラのメソッドで行います。@Valid アノテーションを使い、バリデーションの結果を BindingResult で確認します。

```java
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PostMapping;
import javax.validation.Valid;

@Controller
public class UserController {

    @PostMapping("/register")
    public String registerUser(@Valid UserForm userForm, BindingResult result) {
        if (result.hasErrors()) {
            // バリデーションエラーがある場合、エラーメッセージを表示
            return "registrationForm";
        }
        // 登録処理を実行
        return "success";
    }
}
```

4. カスタムバリデーション
必要に応じて、独自のバリデーションロジックを作成することもできます。カスタムバリデーションを実装するには、@Constraint アノテーションと ConstraintValidator インターフェースを使用します。

まとめ
トランザクション管理: Spring Bootでは、@Transactional アノテーションを使ってトランザクションを簡単に管理できます。これにより、データベース操作中にエラーが発生した際に自動的にロールバックを行うことが可能です。

バリデーション: Spring Bootは、標準のJava Bean Validationをサポートしており、エンティティやフォームデータの検証が簡単に行えます。さらに、カスタムバリデーションも実装可能です。