Java | JPA |トランザクション処理

に公開

JPA

トランザクション処理

  • JPA(Java Persistence API)におけるトランザクション処理は、データベース操作を一貫性のある状態で行うための重要な機能。
  • トランザクションは、複数のデータベース操作を一つの単位として扱い、すべての操作が成功するか、すべてが失敗するかのいずれかを保証する。

トランザクションの基本的な流れ

流れ 内容
トランザクションの開始 トランザクションを開始する。
データベース操作 エンティティの作成、更新、削除などの操作を行う。
トランザクションのコミット すべての操作が成功した場合、トランザクションをコミットして変更をデータベースに反映させる。
トランザクションのロールバック 何らかのエラーが発生した場合、トランザクションをロールバックして、すべての変更を元に戻す。

具体例

JPAを使用したトランザクション処理の具体例。

[ユーザーのアカウントに対して金額を振り込む処理の例]

  • この例では、UserServiceクラスのtransferFundsメソッドがトランザクションを管理している。

  • 振込元と振込先のユーザーを取得し、残高を確認した後、両方のユーザーの残高を更新する。

  • すべての操作が成功した場合はトランザクションをコミットし、エラーが発生した場合はロールバックする。

  • JPAを使用することで、トランザクション処理を簡潔に実装することができる。

  • トランザクション管理はデータの整合性を保つために非常に重要。

エンティティの定義

まず、Userエンティティを定義する。


import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class User {
    @Id
    private Long id;
    private String name;
    private double balance;

    // ゲッターとセッター
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getBalance() {
        return balance;
    }

    public void setBalance(double balance) {
        this.balance = balance;
    }
}

トランザクション処理の実装

  • 次に、振り込み処理を行うサービスクラスを作成する。

import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;

public class UserService {
    private EntityManager entityManager;

    public UserService(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    public void transferFunds(Long fromUserId, Long toUserId, double amount) {
        EntityTransaction transaction = entityManager.getTransaction();
        try {
            transaction.begin();

            // 振込元ユーザーの取得
            User fromUser = entityManager.find(User.class, fromUserId);
            // 振込先ユーザーの取得
            User toUser = entityManager.find(User.class, toUserId);

            // 残高の確認
            if (fromUser.getBalance() < amount) {
                throw new IllegalArgumentException("残高が不足しています。");
            }

            // 残高の更新
            fromUser.setBalance(fromUser.getBalance() - amount);
            toUser.setBalance(toUser.getBalance() + amount);

            // 変更をデータベースに反映
            entityManager.merge(fromUser);
            entityManager.merge(toUser);

            // トランザクションのコミット
            transaction.commit();
        } catch (Exception e) {
            // エラーが発生した場合はロールバック
            if (transaction.isActive()) {
                transaction.rollback();
            }
            throw e; // エラーを再スロー
        }
    }
}

参考サイト

Discussion