Enterprise 中級

手動JPAトランザクションと宣言的@Transactionalの比較

冗長なbegin/commit/rollbackブロックを単一の@Transactionalアノテーションに置き換える。

✕ Java EE
@PersistenceContext
EntityManager em;

public void transferFunds(Long from, Long to,
                          BigDecimal amount) {
    EntityTransaction tx = em.getTransaction();
    tx.begin();
    try {
        Account src = em.find(Account.class, from);
        Account dst = em.find(Account.class, to);
        src.debit(amount);
        dst.credit(amount);
        tx.commit();
    } catch (Exception e) {
        tx.rollback();
        throw e;
    }
}
✓ Jakarta EE 8+
@ApplicationScoped
public class AccountService {
    @PersistenceContext
    EntityManager em;

    @Transactional
    public void transferFunds(Long from, Long to,
                              BigDecimal amount) {
        var src = em.find(Account.class, from);
        var dst = em.find(Account.class, to);
        src.debit(amount);
        dst.credit(amount);
    }
}
このコードに問題がありますか? お知らせください。
🗑️

ボイラープレートなし

1つのアノテーションが、繰り返されるbegin/commit/rollbackのtry-catchブロックを置き換えます。

🛡️

安全なロールバック

コンテナが非チェック例外時のロールバックを保証します——catchブロックを忘れるリスクがありません。

📐

宣言的制御

伝播・分離レベル・ロールバックルールをアノテーション属性で表現できます。

旧来のアプローチ
手動トランザクション
モダンなアプローチ
@Transactional
JDKバージョン
11
難易度
中級
手動JPAトランザクションと宣言的@Transactionalの比較
利用可能

Jakarta EE 8 / Java 11以降、広く利用可能

手動のトランザクション管理では、try-catchブロックで囲まれた明示的なbegin()・commit()・rollback()呼び出しが必要で、サービスメソッドごとにこのボイラープレートを繰り返します。@Transactionalアノテーションはライフサイクル管理をコンテナに委ねます。メソッド実行前にトランザクションを開始し、成功時にコミット、RuntimeException発生時に自動でロールバックします。

共有 𝕏 🦋 in