The English version of quarkus.io is the official project site. Translated sites are community supported on a best-effort basis.
このページを編集

Quarkus Extension for Spring Transaction API

While users are encouraged to use Jakarta @Transactional annotations directly, Quarkus provides a compatibility layer for Spring @Transactional in the form of the spring-tx extension.

This guide explains how a Quarkus application can leverage the Spring @Transactional annotation to manage transactions.

前提条件

このガイドを完成させるには、以下が必要です:

  • 約15分

  • IDE

  • JDK 17+がインストールされ、 JAVA_HOME が適切に設定されていること

  • Apache Maven 3.9.16

  • 使用したい場合は、 Quarkus CLI

  • ネイティブ実行可能ファイルをビルドしたい場合、MandrelまたはGraalVM(あるいはネイティブなコンテナビルドを使用する場合はDocker)をインストールし、 適切に設定していること

  • Spring DI エクステンションにある程度慣れている

Maven プロジェクトの作成

まず、新しいプロジェクトが必要です。以下のコマンドで新しいプロジェクトを作成します。

コマンドラインインタフェース
quarkus create app org.acme:spring-tx-quickstart \
    --extension='spring-web,spring-di,spring-tx,spring-data-jpa,jdbc-postgresql' \
    --no-code
cd spring-tx-quickstart

Gradleプロジェクトを作成するには、 --gradle または --gradle-kotlin-dsl オプションを追加します。

Quarkus CLIのインストールと使用方法の詳細については、 Quarkus CLI ガイドを参照してください。

Maven
mvn io.quarkus.platform:quarkus-maven-plugin:3.37.4:create \
    -DprojectGroupId=org.acme \
    -DprojectArtifactId=spring-tx-quickstart \
    -Dextensions='spring-web,spring-di,spring-tx,spring-data-jpa,jdbc-postgresql' \
    -DnoCode
cd spring-tx-quickstart

Gradleプロジェクトを作成するには、 -DbuildTool=gradle または -DbuildTool=gradle-kotlin-dsl オプションを追加します。

Windowsユーザーの場合:

  • cmdを使用する場合、(バックスラッシュ \ を使用せず、すべてを同じ行に書かないでください)。

  • Powershellを使用する場合は、 -D パラメータを二重引用符で囲んでください。例: "-DprojectArtifactId=spring-tx-quickstart"

This command generates a project which imports the spring-tx, spring-di, spring-web, and spring-data-jpa extensions.

If you already have your Quarkus project configured, you can add the spring-tx extension to your project by running the following command in your project base directory:

コマンドラインインタフェース
quarkus extension add spring-tx
Maven
./mvnw quarkus:add-extension -Dextensions='spring-tx'
Gradle
./gradlew addExtension --extensions='spring-tx'

これにより、ビルドファイルに以下が追加されます:

pom.xml
<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-spring-tx</artifactId>
</dependency>
build.gradle
implementation("io.quarkus:quarkus-spring-tx")

Define the entity

このガイドでは、以下のJPA Entityを使用しています。

package org.acme.spring.tx;

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;

@Entity
public class Fruit {

    @Id
    @GeneratedValue
    private Long id;

    private String name;

    public Fruit() {
    }

    public Fruit(String name) {
        this.name = name;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

リポジトリの定義

In a typical Spring Data fashion, create a repository for Fruit:

package org.acme.spring.tx;

import java.util.List;

import org.springframework.data.repository.CrudRepository;

public interface FruitRepository extends CrudRepository<Fruit, Long> {

    List<Fruit> findByName(String name);
}

Creating a transactional service

Now let’s create a service that uses Spring’s @Transactional annotation to manage transactions. Create src/main/java/org/acme/spring/tx/FruitService.java with the following content:

package org.acme.spring.tx;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class FruitService {

    @Autowired
    FruitRepository fruitRepository;

    @Transactional (1)
    public Fruit addFruit(String name) {
        return fruitRepository.save(new Fruit(name));
    }

    @Transactional(propagation = org.springframework.transaction.annotation.Propagation.REQUIRED) (2)
    public void addMultipleFruits(List<String> names) {
        for (String name : names) {
            fruitRepository.save(new Fruit(name));
        }
    }
}
1 The Spring @Transactional annotation is automatically transformed into a Jakarta @Transactional annotation at build time.
2 You can specify propagation attributes just like in Spring. REQUIRED is the default.

You can also place @Transactional at the class level to make all public methods transactional:

package org.acme.spring.tx;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional (1)
public class TransactionalService {

    public void doSomething() {
        // this method is transactional
    }

    public void doSomethingElse() {
        // this method is also transactional
    }
}
1 All public methods of this class are transactional.

Controlling rollback behavior

Spring’s rollbackFor and noRollbackFor attributes are supported:

package org.acme.spring.tx;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class RollbackService {

    @Transactional(rollbackFor = BusinessException.class) (1)
    public void performBusinessOperation() throws BusinessException {
        // if BusinessException is thrown, the transaction rolls back
    }

    @Transactional(noRollbackFor = NonCriticalException.class) (2)
    public void performTolerantOperation() throws NonCriticalException {
        // if NonCriticalException is thrown, the transaction still commits
    }
}
1 The transaction will roll back if BusinessException (or a subclass) is thrown.
2 The transaction will NOT roll back if NonCriticalException is thrown.

Jakarta RESTリソースの更新

With the repository and service in place, create the Jakarta REST resource that will use the FruitService. Create src/main/java/org/acme/spring/tx/FruitResource.java with the following content:

package org.acme.spring.tx;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class FruitResource {

    @Autowired
    FruitService fruitService;

    @Autowired
    FruitRepository fruitRepository;

    @GetMapping("/fruits")
    public List<Fruit> list() {
        return (List<Fruit>) fruitRepository.findAll();
    }

    @PostMapping("/fruits")
    public Fruit add(@RequestBody Fruit fruit) {
        return fruitService.addFruit(fruit.getName());
    }
}

アプリケーションをパッケージ化して実行する

Quarkus Dev Services will automatically start a PostgreSQL container in dev and test modes, so no manual database configuration is needed.

次のコマンドでアプリケーションを実行します。

コマンドラインインタフェース
quarkus dev
Maven
./mvnw quarkus:dev
Gradle
./gradlew --console=plain quarkusDev

In another terminal, add a fruit:

curl -X POST -H "Content-Type: application/json" -d '{"name": "Apple"}' http://localhost:8080/fruits

Then list all fruits:

curl http://localhost:8080/fruits

いつものように、アプリケーションは以下の方法でパッケージ化されます。

コマンドラインインタフェース
quarkus build
Maven
./mvnw install
Gradle
./gradlew build

そして、 java -jar target/quarkus-app/quarkus-run.jar を使って実行します。

次のようにネイティブ実行可能ファイルを生成することもできます。

コマンドラインインタフェース
quarkus build --native
Maven
./mvnw install -Dnative
Gradle
./gradlew build -Dquarkus.native.enabled=true

Supported Spring @Transactional features

The table below summarizes the supported attributes:

Table 1. Supported Spring @Transactional attributes
属性 ステータス Comments

propagation

Supported

All values except NESTED: REQUIRED (default), REQUIRES_NEW, SUPPORTS, MANDATORY, NOT_SUPPORTED, NEVER. NESTED causes a build-time error.

rollbackFor

Supported

rollbackForClassName

Supported

noRollbackFor

Supported

noRollbackForClassName

Supported

readOnly

Unsupported

Ignored with a warning

timeout / timeoutString

Unsupported

Ignored with a warning

isolation

Unsupported

Only DEFAULT is accepted; other values are ignored with a warning

value / transactionManager

Unsupported

Quarkus manages the transaction manager

label

Unsupported

Ignored with a warning

重要な技術的注意点

Quarkus での Spring サポートは、Spring Application Context を開始せず、Spring インフラストラクチャークラスも実行しないことに注意してください。Spring クラスとアノテーションは、メタデータの読み取りにのみ使用されるか、ユーザーコードメソッドの戻り値の型またはパラメーター型として使用されます。エンドユーザーにとってそれが意味することは、任意の Spring ライブラリーを追加しても効果がないということです。さらに、Spring インフラストラクチャークラス (たとえば、 org.springframework.beans.factory.config.BeanPostProcessor など) は実行されません。

関連コンテンツ