Java
spring
DependencyInjection
Database
spring-boot

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

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

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

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

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

https://ameblo.jp/kochablo/entry-11578714824.html

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

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

ダメな例:no_good:

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を投げる処理
  }
}

これではいけませんね。

良い例:ok_woman:

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しとるメソッドを呼んだらええっちゅうこっちゃ。