SpringBootの@Transactionalが効かないときは


SpringBootを使っていてDBへの登録時にTransaction管理をする必要が出てきた。

publicなメソッドに@TransactionalアノテーションをつけてExceptionを発生させれば自動的にロールバックしてくれるらしい。

というわけでやってみたのだが、ぜんっっっっっっっっっっっっぜんうまくいかない。
アノテーションに与える設定を色々と変えてみたがちっともロールバックされない。

2時間か3時間程度格闘し、Webの海をクロールしていたところ神々しい灯台が見えた。

一撃でうまくいった。先駆者兄貴に感謝。マジ感謝。

ただ、「直接呼ばないといけない」ってどういうことやねんと思ったので
先駆者兄貴のように困っている存在をたすけられたらと思い以下に詳述する。

ダメな例

SampleController.java
class SampleController{
  @Autowired
  private SampleService sampleService;

  public String sample(){
    sampleService.transactionalInsert();
    return "sampleView";
  }
}
SampleService.java
class SampleService{

  public void transactionalInsert(){
    doInsert();
  }

  @Transactional
  public void doInsert(){
    // なんやかんやDBにInsertとかする処理
    // うまくいかなかったらRuntimeExeptionを投げる処理
  }
}

これではいけませんね。

良い例

SampleController.java
class SampleController{
  @Autowired
  private SampleService sampleService;

  public String sample(){
    sampleService.doInsert();
    return "sampleView";
  }
}
SampleService.java
class SampleService{

  public void transactionalInsert(){
    doInsert();
  }

  @Transactional
  public void doInsert(){
    // なんやかんやDBにInsertとかする処理
    // うまくいかなかったらRuntimeExeptionを投げる処理
  }
}

おわかりいただけただろうか。
なんせ@Autowiredしとるクラスから@Transactionalしとるメソッドを呼んだらええっちゅうこっちゃ。