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


82

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

@Transactionalアノテーションなしでクエリも試したので、spring-dataを使用している場合はを使用する必要がないことに気付きました。

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

作品:

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

また動作します:

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

前もって感謝します!

回答:


140

実際にあなたの質問は何ですか?@Repository注釈の使用法または@Transactional

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

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

以下のようなメソッドを読み込みfindAll()してfindOne(…)使用している@Transactional(readOnly = true)厳密には必要ではないが、トランザクション・インフラストラクチャーにおけるいくつかの最適化をトリガする(設定FlushModeするMANUAL閉じるときにプロバイダが潜在的に汚れチェックをスキップ永続させるためにEntityManager)。それを超えて、フラグはJDBC接続にも設定され、そのレベルでさらに最適化されます。

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


8
つまり、すべてのDAOメソッドの追加/編集/削除クエリで@Transactionalを使用し、選択クエリで@Transaction(readOnly = true)を使用する必要がありますか?
Byron Voorbach 2012

20
丁度。これを行う最も簡単な方法は@Transactional(readOnly = true)、インターフェイスで使用し(通常、ほとんどの場合ファインダーメソッドが含まれているため)、変更するクエリメソッドごとにこの設定をプレーンでオーバーライドすることです@Transactional。それは実際にはで行われている方法SimpleJpaRepositoyです。
オリバードロトボーム2012年

@Oliverは、包括的な説明に感謝します。しかし、他のリンク[transaction-pit-falls] < ibm.com/developerworks/java/library/j-ts1/index.html#listing8 >を通過している間、。それは言う、「ボトムラインは、あなたがORMベースのフレームワークを使用する場合、読み取り専用フラグは無視され、かなり役に立たないと、ほとんどの場合である。しかし、あなたはまだそれを使う、という場合は、常に支持体に伝播モードを設定することです。 。これを読んだ後、(readOnly = true)を単独で使用する必要があるかどうかわかりません..常にSUPPORTSとして伝播モードで使用する必要があります。
Anupam Gupta 2013

8
記事のこのセクションでは、ほぼすべてが間違っています。記述していないことを示すことにより、JDBC駆動型はDB対話のパフォーマンスを向上させることができます(向上します)。また、誤って発行された書き込みを検出して拒否することもできます。さらに、Springは読み取り専用モードでJPA / Hibernateフラッシュを無効にします。これは、プロバイダーがダーティチェックを実行する必要がないため、大きなオブジェクトグラフを読み取る場合にパフォーマンスに大きな影響を与える可能性があります。フラグはトランザクション自体に大きな影響を与えないかもしれませんが、それは考慮すべきすべてではありません。
オリバードロトボーム2013年

大きなオブジェクトグラフの場合や、多数の管理対象オブジェクトをロードするユースケースの場合のパフォーマンスの向上を保証できます。
シャイレンダ2015

3

質問は少し広く、データアクセス層の注釈で減らすことはできないと思います。アプリケーションのスタック全体、適用するトランザクション戦略などを考慮する必要があります。IBMdeveloperworksサイトにMarkRichardsによるこのトピックに関する非常に包括的な一連の記事があります。最初のものはここにあります:https//developer.ibm.com/articles/j-ts1/

宜しくお願いします


2

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

これは@Repository、チェックされていないSQL例外をSpring Excpetionに変換するために使用され、対処する必要がある唯一の例外はDataAccessException


10
これは一般的にSpringを使用する場合に当てはまりますが、Spring DataリポジトリはすでにSpringプロキシによってサポートされているため、@ Repositoryを使用しても違いはありません。
アレクサンダーBlomskøld

0

また、@ Transactionalアノテーションを使用してレコードをロックし、別のスレッド/リクエストが読み取りを変更しないようにします。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.