5

(他のタスクの中でも)次のコードでSpringバッチジョブを開始する単純なSpring-Serviceがあります。

@Autowired
private JobRegistry jobRegistry;

@Autowired
private JobLauncher jobLauncher;

public void startMyJob() {
    Job job = jobRegistry.getJob("myJobName");
    JobParameters jobParameters = new JobParametersBuilder().toJobParameters();
    jobLauncher.run(job, jobParameters);
}

これは、Serivce-Method が呼び出されたときにアクティブなトランザクションがない限り、正常に機能します。ただし、アクティブなトランザクションでは、次の例外が発生します。

Caused by: java.lang.IllegalStateException: Existing transaction detected in JobRepository. Please fix this and try again (e.g. remove @Transactional annotations from client).

私の手の届かないフレームワークコードが原因で暗示されているため、既存のトランザクションを簡単に削除することはできません。

では、このコンテキスト内でジョブを開始するにはどうすればよいでしょうか? 新しいジョブは、既存のトランザクションを使用しないでください。独自のトランザクションを開始することもできますが、それを機能させるにはどのように構成すればよいでしょうか?

4

4 に答える 4

6

同様の問題がありました。特に、私は で注釈が付けられたクラス内からジョブを開始していました@Transactional(propagation = Propagation.REQUIRES_NEW)。これを回避するために、アクティブな取引がない場所から仕事を始めました。次に、上記のようにあなたの問題に遭遇しました-そして、これが私がそれを解決した方法です:

validateTransactionStateJobRepository で false に設定- 呼び出したクラスで自動的に作成されたトランザクションを無視するようになりましたItemProcessor(上記で説明したように、このクラスには @Transcational のアノテーションが付けられているため)。

これにより、私の仕事はうまくいきました。しかし、現在 2 つの未処理のトランザクションを扱っているかどうかわからなかったので、そうではないことを確認したかったのです。そのため、クラス レベルのトランスケーショナル アノテーションも削除し、Itemprocessor によって呼び出されるものを除くすべてのパブリック メソッドに移動しました。したがって、私は問題を解決しました。

于 2015-02-19T14:02:27.250 に答える
3

JobLauncher と同じ署名を持つ run メソッドを持ち、実際の署名にデリゲートしますが、Spring の @Async でマークされた別の Bean AsyncJobLauncher を作成することで、これに対処しました。そのため、ジョブの起動は新しいスレッドのバックグラウンドで発生したため、独自のトランザクションでした。

于 2014-08-01T17:08:36.000 に答える
2

を使用AbstractJobRepositoryFactoryBean.ValidateTransactionStateしますが、慎重に使用してください (警告: ドラゴンが先にいます)。

別のトランザクションを使用するには、 @Transactional() としてマークされSimpleJobLauncher.executorたメソッドでカスタムを注入できます (またはカスタムを作成して、メソッドで同じトリックを実行します)。Executor.runJobLauncherrun

私は問題に直面していないので試していませんが、希望は役に立ちます。

于 2013-08-08T12:49:39.437 に答える