SpringBootとトランザクション

SpringBoot

アノテーションでトランザクションの管理

SpringBootでは、アノテーションによるトランザクション管理が可能です。
メソッドやクラスの前にTransactionalアノテーションを付与することで、メソッドが呼び出されたタイミングでトランザクションが開始され、メソッドが正常終了した場合はコミットします。
例外で終了した場合はロールバックされます。
以下がアノテーションの付与例です。

// メソッドでトランザクションを指定する場合
public class HogeServiceImpl implements HogeService {

        @Transactional
        public void insert(Fuga fuga) {
        }
}
// クラスでトランザクションを指定する場合
@Transactional
public class HogeServiceImpl implements HogeService {
        
        public void insert(Fuga fuga) {
        }
}

注意事項として、以下が挙げられます。

ロールバックはデフォルトRuntimeExceptionとError

デフォルトではRuntimeExceptionがスローされるとロールバックしますが、RuntimeExceptionでない例外ではロールバックされません。

This annotation type is generally directly comparable to Spring's RuleBasedTransactionAttribute class, and in fact AnnotationTransactionAttributeSource will directly convert the data to the latter class, so that Spring's transaction support code does not have to know about annotations. If no custom rollback rules apply, the transaction will roll back on RuntimeException and Error but not on checked exceptions

https://docs.spring.io/spring-framework/docs/5.3.9/javadoc-api/org/springframework/transaction/annotation/Transactional.html

以下のように、rollbackFor識別子を追加して、ロールバック対象の例外を明記する事でRuntimeException以外でもロールバックすることができます。

// メソッドでトランザクションを指定する場合
public class HogeServiceImpl implements HogeService {

        @Transactional(rollbackFor = Exception.class)
        public void insert(Fuga fuga) {
        }
}

トランザクションが未生成の場合は作る、生成済みの場合利用するのがデフォルト

SpringBootのトランザクションには,伝搬レベルというのがあります。伝搬レベルには以下があります。

  • REQUIRED
  • REQUIRES_NEW
  • SUPPORTS
  • NOT_SUPPORTED
  • MANDATORY
  • NESTED
  • NEVER

デフォルトREQUIREDとなっています。
REQUIREDはトランザクションが存在しない場合、新規にトランザクションを開始し、
すでに存在する場合はそのトランザクションを利用します。

public class HogeServiceImpl implements HogeService {

        @Autowired
        private FugaService fugaService;

        @Transactional
        public void insert(Hoge hoge) {
                Fuga fuga = new Fuga();
                fugaService.insert(fuga);
        }
}

public class FugaServiceImpl implements FugaService {

        @Transactional
        public void insert(Fuga fuga) {
        }
}
sequenceDiagram participant c as Caller participant h as HogeService participant f as FugaService c->>+h: insert Note over h: トランザクション開始 h->>+f: insert Note right of f: トランザクションが開始しているため新たにトランザクションは開始しない f-->>-h: 戻り Note over h: コミット h-->>-c: 戻り

コメント

タイトルとURLをコピーしました