はじめに
Spring Boot でデータを扱うとき、
@Transactional というアノテーションをよく目にします。
- どこに付ければいいの?
- 何をしてくれるの?
- 付け忘れるとどうなるの?
こういった疑問は、実務でも頻出です。
この記事では、@Transactional の基本を
やさしく・実務寄り で整理していきます。
まずはコードから見ていきましょう。
まずはコードを確認
@Service
public class OrderService {
@Transactional
public void createOrder(OrderRequest req) {
// 複数の DB 操作
orderRepository.save(order);
stockRepository.decrease(req.getItemId());
}
}このように、
複数の DB 操作をまとめて 1 つの処理として扱う
のが @Transactional の役割です。
@Transactional を一言でいうと…
「複数の DB 操作をまとめて、成功なら全部反映・失敗なら全部なかったことにする仕組み」
です。
- 成功 → commit
- 失敗 → rollback
この“全部まとめて扱う”のがトランザクションです。
もう少し深く理解する
commit(コミット)
すべての処理が成功したら、DB に反映します。
rollback(ロールバック)
途中で例外が起きたら、 すべての変更を取り消します。
例:
- 注文は保存された
- でも在庫更新でエラー
→ 注文も保存されなかったことにする
これがトランザクションの強さです。
@Transactional を付ける場所
基本は Service 層
理由
- Controller は HTTP の層
- Repository は DB の層
- Service が“業務処理のまとまり”を持つ層だから
@Service
@Transactional
public class OrderService { ... }クラスに付けると、すべての public メソッドが対象になります。
@Transactional のよく使うオプション
readOnly = true
読み取り専用のときに使います。
@Transactional(readOnly = true)
public User findUser(Long id) { ... }メリット:
- パフォーマンスが良くなる
- 不要な更新を防げる
rollbackFor
特定の例外でロールバックしたいとき。
@Transactional(rollbackFor = Exception.class)デフォルトでは RuntimeException のみロールバック対象です。
実務でよくあるつまずき
private メソッドには効かない
@Transactional は public メソッド にしか適用されません。
同じクラス内のメソッド呼び出しには効かない
自己呼び出し(self-invocation)は AOP が働かないため、
@Transactional が無視されます。
チェック例外ではロールバックされない
デフォルトでは RuntimeException のみロールバック対象です。
Controller に付けるのはアンチパターン
HTTP と DB の境界が曖昧になります。
@Transactional が必要な場面
複数の Repository を操作するとき
orderRepository.save();
stockRepository.update();更新 → 参照 → 更新 のような複合処理
業務ロジックのまとまりを守るために必要です。
途中で例外が起きたら全部取り消したいとき
データの整合性を守るために必須です。
@Transactional が不要な場面
単純な参照(findById など)
readOnly = true で十分。
単一の save のみ
Repository が内部でトランザクションを扱うため、
必ずしも Service に付ける必要はありません。
あわせて知っておきたいポイント
トランザクションは「境界」を決めるもの
Service 層に付ける理由はここにあります。
Spring のトランザクションは AOP で実現されている
メソッドの前後に処理を挟む仕組みです。
@Transactional はネストできる
ただし挙動は少し複雑なので注意。
まとめ
@Transactional は、
「複数の DB 操作をまとめて 1 つの処理として扱うための仕組み」
です。
- 成功 → commit
- 失敗 → rollback
- 基本は Service 層に付ける
- readOnly や rollbackFor も便利
- private メソッドや自己呼び出しには効かない
難しく聞こえますが、
「業務処理のまとまりを守るためのアノテーション」
と理解できれば十分です。

@Transactional を理解すると、
データの整合性を守る設計が一気にクリアになります。
“どこに付けるべきか”が分かるだけで、
実務の安定感がぐっと上がります。
あなたの開発が、今日より少しだけ楽になりますように。

全部成功したら OK、失敗したらなかったことに…
やさしい仕組みだね。

コメント