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?

【SpringBoot]@Transactionalについて

Posted at

Transactionalアノテーションとは

「トランザクション」を利用するために必要なアノテーション。
「トランザクション」とは、データベースを利用する一連の処理を一括で実行する機能であり、処理中に例外が起こった場合は、自動でロールバックしてくれる。

トランザクションを利用しなかった場合

データアクセス処理中に、途中で外部からデータベースにアクセスされ、データが変更されたりすると、データの整合性に問題が発生してしまう。そうしたトラブルを防ぐためにトランザクションは必要となる。

使い方

サービスクラスに「@Transactional」を付与することで、そのクラス内の全てのメソッドにトランザクションが適用される。
※特定のメソッドにのみ適用したい場合は、該当メソッドにのみアノテーションを付与する。

例:Controllerクラス

TestController.java
public class TestController {

    @Autowired
    TestService testService;

    @PostMapping("/post")
    public void postTest() {
        testService.insertA();
    }
}

例:Serviceクラス

TestService.java
@Service
@Transactional
public class TestService {

    @Autowired
    TestDao testDao;

    public void insertA() {
        // 挿入レコード用意
        Fruit fruit = new Fruit();
        fruit.setId("1");
        fruit.setName("apple");
        fruit.setPrice("100");

        // レコード挿入
        testDao.insert(fruit);

        // 例外発生
        throw new RuntimeException();
    }
}

実行結果

正常にロールバックされている。

mysql> select * from fruit;
Empty set (0.00 sec)

※注意点

トランザクションが機能するのは、このサービスクラスをDIしたクラスから直接呼び出されているメソッドのみということ。以下のような場合、ロールバックされません。

TestService.java
@Service
public class TestService {

    @Autowired
    TestDao testDao;

    // これがControllerから直接呼び出されているメソッド
    public void insertA() {
        insertB();
    }

    // Controllerから直接呼び出されていないメソッドに付与
    @Transactional
    public void insertB() {
        // 挿入レコード用意
        Fruit fruit = new Fruit();
        fruit.setId("1");
        fruit.setName("apple");
        fruit.setPrice("100");

        // レコード挿入
        testDao.insert(fruit);

        // 例外発生
        throw new RuntimeException();
    }
}

実行結果

ロールバックされず、データは挿入される。

mysql> select * from item;
+----+-------+-------+
| ID | NAME  | PRICE |
+----+-------+-------+
| 1  | apple | 100   |
+----+-------+-------+

属性値について

指定可能なプロパティは9種類ほどある模様
詳しい内容はこちらの記事を参照

本稿では、その中でも、開発時によく利用しているreadOnly属性について解説する。

【readOnly属性】

・readOnly属性(デフォルトはfalse)を true に設定すると、読み取り専用のトランザクションと見なし、レコードへの書き込みや変更を伴う操作が走った際に例外を投げてくれる。

java
@Service
public class UserService {

    /** 更新系 **/
    @Transactional(readOnly = true)
    public User insertFruit() {
    
        // 挿入レコード用意
        Fruit fruit = new Fruit();
        fruit.setId("1");
        fruit.setName("apple");
        fruit.setPrice("100");

        // レコード挿入
        testDao.insert(fruit);
    }
}

実行結果

更新処理は許可されていないため、以下のようなエラーが出力される。

java.sql.SQLException: Connection is read-only. Queries leading to data modification are not allowed
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?