1

私のアプリケーションには、ジョブ出力を内部的にポーリングするサービスがあります。ジョブのステータスが「進行中」から「完了」に変わるまでポーリングします。ジョブを処理すると、別のシステムがジョブのステータスを「完了」に更新しようとしています。

ここでの問題は、ジョブのステータスが DB から初めてポーリングされたときに、ステータスが「進行中」になることです。しかし、後でジョブのステータスが他のプロセスによって変更された場合でも、「進行中」と表示されます。休止状態のクエリがトランザクション外で実行されているため、問題は DB 分離レベル (反復可能読み取り) にはありません。結果がキャッシュされていると思われ、同じクエリが同じセッションで実行されると、キャッシュされた結果が得られます。

同じクエリが同じセッションで複数回実行されたときに、DB から更新されたデータを取得するにはどうすればよいですか。

よろしく、チャンドゥ

4

1 に答える 1

2

アップデート

コメントによると、Spring JPA データを使用する Spring Boot アプリケーションです。そして、serviceクラスはループを使用して 5 分ごとにステータスをチェックします。つまり、実質的に同じトランザクション、つまり同じセッション内にあります。

そのため、呼び出さない限りrefresh()evict() and reloadデータベースから更新された状態を確認することはできません。

しかし問題は、 で呼び出すことができるCrudRepositoryようなメソッドを が公開していないことです。refresh()entity manager

したがって、オプションはCrudRepository、メソッド say を追加することrefreshEntity(...)です。このメソッドは内部的に を呼び出しますentityManager.refresh()。最後に、serviceループはこのメソッドを呼び出してrefreshEntity(..)、更新されたデータを取得できます。

例として:

public interface MyStatusRepository {
   void refreshEntity(StatusEntity se);
}

public interface StatusRepository extends CrudRepository<StatusEntity, Long>, MyStatusRepository {
    ...
}

@Repository
public class MyStatusRepositoryImpl implements MyStatusRepository {
    @PersistenceContext
    private EntityManager entityManager;

    @Override
    public void refreshEntity(StatusEntity se); {
        entityManager.refresh(se);
    }
    ...
}

拡張リポジトリの詳細については、上記のリンクを参照してください。

他のオプションは、 を拡張する代わりに、クラス自体で を自動配線し、その上で を呼び出すCrudRepositoryことでした。これも同様に機能しますが、既存の設計からの逸脱になります。entityManagerservicerefresh()

于 2016-03-30T15:39:36.737 に答える