web-dev-qa-db-ja.com

Spring Dataで@Transactionalを使用する方法は?

私は、Spring-data、Hibernate、MySQL、JPAプロジェクトに取り組み始めたばかりです。手作業でクエリを作成することを心配する必要がないように、spring-dataに切り替えました。

注釈なしでクエリも試したため、spring-dataを使用している場合は@Transactionalを使用する必要がないことに気付きました。

@Transactionalアノテーションを使用すべき/使用すべきでない特定の理由はありますか?

作品:

@Transactional
public List listStudentsBySchool(long id) {
    return repository.findByClasses_School_Id(id);
}

また機能します:

public List listStudentsBySchool(long id) {
    return repository.findByClasses_School_Id(id);
}

前もって感謝します!

66
Byron Voorbach

実際にあなたの質問は何ですか? _@Repository_アノテーションまたは_@Transactional_の使用。

_@Repository_はまったく宣言する必要がありません。宣言するインターフェイスは、Spring Dataインフラストラクチャが作成し、とにかく例外変換をアクティブにするプロキシによってサポートされるためです。したがって、Spring Dataリポジトリインターフェースでこのアノテーションを使用しても、まったく効果はありません。

_@Transactional_-JPAモジュールの場合、プロキシをサポートする実装クラスにこの注釈があります( SimpleJpaRepository )。これには2つの理由があります。まず、オブジェクトの永続化と削除にはJPAでのトランザクションが必要です。したがって、トランザクションが実行されていることを確認する必要があります。これには、メソッドに_@Transactional_アノテーションを付けます。

findAll()findOne(…)などの読み取りメソッドは@Transactional(readOnly = true)を使用していますが、これは厳密には必要ありませんが、トランザクションインフラストラクチャでいくつかの最適化をトリガーします(FlushModeMANUALは、EntityManagerを閉じるときに永続性プロバイダーがダーティチェックを潜在的にスキップできるようにします。さらに、フラグはJDBC接続にも設定され、そのレベルでさらに最適化されます。

使用するデータベースによっては、テーブルロックを省略したり、誤ってトリガーする可能性のある書き込み操作を拒否することもできます。したがって、クエリメソッドにも@Transactional(readOnly = true)を使用することをお勧めします。これにより、リポジトリインターフェースにその注釈を簡単に追加できます。そのインターフェイスで宣言または再装飾した可能性のある操作メソッドに、プレーンな_@Transactional_を必ず追加してください。

115
Oliver Drotbohm

質問はもう少し広範で、データアクセスレイヤーの注釈で減らすことはできないと思います。アプリケーションのスタック全体、適用するトランザクション戦略などを考慮する必要があります。 IBM developerworksサイトには、Mark Richardsによるこのトピックに関する非常に包括的な記事があります。最初のものはここにあります: http://www.ibm.com/developerworks/Java/library/j-ts1/index.html

宜しくお願いします

3
dgiffone

@Repository注釈を使用する必要があります

これは、未チェックのSQL例外をSpring Excpetionに変換するために@Repositoryが使用され、対処すべき唯一の例外はDataAccessExceptionであるためです。

1
danny.lesnik