0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Springの@Transactional 備忘録

Posted at

@Transactionalとは?

Springではクラスやメソッド、及びインタフェースに付ける@Transactionalというアノテーションを提供している。
@Transactionalを付けたら、*宣言的トランザクションの管理対象になりトランザクションの属性が付与される。
*宣言的トランザクション:AOPを利用し、コードの外部からトランザクションの機能を付与し属性を指定できるようにすること。⇔明示的トランザクション

使用例

サービスレイヤー

@Transactionalはどこでも使えるが、一般的にビジネスロジックに該当するサービスレイヤーのメソッドに書くのが良い。なぜなら、DBから取得したデータを取り扱うところがサービスレイヤーだからだ。

@Transactional(readOnly = true)  //★1
@Service
public class WordsService {
    private final WordsRepository wordsRepository;
    
    public List<WordHomeResponseDto> getAllWords() {
        List<Words> result = wordsRepository.findByDeleteFlg(GlobalVariable.FALSE);
        List<WordHomeResponseDto> words = result.stream().map(WordHomeResponseDto::new).collect(Collectors.toList());

        return words;
    }

    @Transactional //★2
    public void edit(WordEditRequestDto requestDto) {
        Words word = wordsRepository.findByWordId(requestDto.getWordId()).orElseThrow(() -> new IllegalArgumentException("該当することばがありません。"));
        word.update(requestDto.getWordName(), requestDto.getWordPronunciation(), requestDto.getWordMeaning(), requestDto.getWordExample());
    }
}

★1:クラスレベルに@Transactionalアノテーションを付けるとその下のメソッドにも全て適用される。つまりgetAllWords()にも@Transactionalが付与されている状態。
★2:★1のように、クラスレベルには全てのメソッドに適応される読み取り専用(readOnly = true)@Transactionalを宣言し、insert, update, deleteをする場合は別途@Transactionalをメソッドに付与するのが良い。微妙な性能の改善ができるようだ。

テストコード

@Transactional  //★
@DataJpaTest
public class WordsRepositoryTest {
    @Autowired
    private WordsRepository wordsRepository;

    @Test
    public void updateWord() {
        //given
        String wordName = "test-word-update";
        String wordPronunciation = "test-pronunciation-update";
        String wordMeaning = "test-meaning-update";
        String wordExample = "did you update your test code?";

        List<Words> originalWordList = wordsRepository.findAll();
        Words word = originalWordList.get(0);

        //when
        word.update(wordName, wordPronunciation, wordMeaning, wordExample);
        List<Words> editedWordList = wordsRepository.findAll();
        word = editedWordList.get(0);

        //then
        assertEquals(word.getWordName(), wordName);
        assertEquals(word.getWordPronunciation(), wordPronunciation);
        assertEquals(word.getWordMeaning(), wordMeaning);
        assertEquals(word.getWordExample(), wordExample);
    }
}

@Transactionalをテストに付けたら、テストコードで行ったDBに対する作業(例えば登録・更新・削除)をテスト完了後ロールバックしてくれる。但し、auto_incrementsequenceで増加したidはトランザクションの管理対象ではないので、ロールバックされない。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?