コードのタイトルからの質問:
@Transactional (readonly = true)
public interface FooService {
void doSmth ();
}
public class FooServiceImpl implements FooService {
...
}
対
public interface FooService {
void doSmth ();
}
@Transactional (readonly = true)
public class FooServiceImpl implements FooService {
...
}
これらをインターフェースに配置できますが、場合によってはトランザクションが終了しない可能性があることに注意してください。 Springドキュメントの Secion 10.5.6 の2番目のヒントを参照してください。
Springでは、インターフェースに注釈を付けるのではなく、@ Transactional注釈を使用して、具体的なクラス(および具体的なクラスのメソッド)のみに注釈を付けることをお勧めします。インターフェイス(またはインターフェイスメソッド)に@Transactionalアノテーションを配置できますが、これは、インターフェイスベースのプロキシを使用している場合に期待どおりに機能します。 Javaアノテーションがインターフェースから継承されないということは、クラスベースのプロキシ(proxy-target-class = "true")またはウィービングベースのアスペクト(mode = " aspectj ")、トランザクション設定はプロキシおよびウィービングインフラストラクチャによって認識されず、オブジェクトはトランザクションプロキシにラップされません。これは明らかに悪いことです。
このため、実装にそれらを配置することをお勧めします。
また、私にとって、トランザクションは実装の詳細のように見えるため、実装クラスに含める必要があります。トランザクションの必要がないロギングまたはテスト実装(モック)のラッパー実装を想像してください。
Springの 推奨 は、インターフェイスではなく具体的な実装に注釈を付けることです。インターフェイスでアノテーションを使用するのは間違っていません。その機能を誤用して、@ Transaction宣言をうっかりバイパスしてしまう可能性があります。
インターフェイスでトランザクション対応の何かをマークし、春に実装クラスのいずれかを参照する場合、springが作成するオブジェクトが@Transactionalアノテーションを尊重しないことは明らかではありません。
実際には、次のようになります。
public class MyClass implements MyInterface {
private int x;
public void doSomethingNonTx() {}
@Transactional
public void toSomethingTx() {}
}
具象クラスでの@Transactionalのサポート:
一般に、API、実装、およびWeb(必要な場合)の3つのセクションでソリューションを設計することを好みます。依存関係を最小限に抑えて、APIを可能な限り軽量/シンプル/ POJOに保つように最善を尽くします。 APIを頻繁に共有する必要がある分散/統合環境でプレイする場合は特に重要です。
@Transactionalを配置するには、APIセクションにSpringライブラリが必要ですが、これは効果的ではありません。そのため、トランザクションが実行されている実装に追加することを好みます。
IFCの予見可能なすべての実装者がTXデータに関心がある限り、インターフェイスに配置しても問題ありません(トランザクションはデータベースだけで処理される問題ではありません)。メソッドがTXを気にしない場合(ただし、Hibernateまたはその他のためにそこに配置する必要がある場合)、Implに配置します。
また、@Transactional
インターフェースのメソッド:
public interface FooService {
@Transactional(readOnly = true)
void doSmth();
}