1

jpa と mysql で playframework 1.2.4 を実行しています。

DB から最初の 20 個のアクティビティを取得し、ステータスをアクティブに設定して他のジョブ インスタンスの実行を停止し、アクティビティを実行してからアクティビティの次のページを取得し、すべてのアクティビティが完了するまで繰り返すジョブがあります。ただし、1 秒おきのページ、またはページ サイズが 20 の 20 レコードをスキップしているようです。私のロジックは次のとおりです。

long total = Activity.count(q, params);
int page = 1;
int pageSize = 20;

int pages = ...

while (page <= pages) {

JPAPlugin.startTx(false);
Collection<Activity> activities = Activity.find(query, params).fetch(page, pageSize);

for (Activity activity : activities) {
    activity.status = ActivityStatus.ACTIVE;
    activity.save();
}
JPAPlugin.closeTx(false);

JPAPlugin.startTx(false);
for (Activity activity : activities) 
    longProcessActivityInAnotherTransaction(activity);
JPAPlugin.closeTx(false);

page++;
}

ただし、データベースには、ステータスACTIVEのレコード1〜20、ステータスACTIVEのない21〜40、ステータスACTIVEの61〜80などがあります。

トランザクションに関係しているようです。while ループ内のすべてのトランザクション開始/終了コードをコメント アウトし、選択したアクティビティの ID を出力すると、すべてのアクティビティが正しく選択されていることがわかります。

また、デバッグ モードで実行し、ループの途中で実行を一時停止し、生成されたクエリを mysql データベースに対して直接実行すると、コードと同じ動作が見られます。ループが実行されていない場合、SQL クエリは期待どおりに実行されます。

私の接続文字列は次のとおりです。

mysql://root:pass@localhost/dbname

助言がありますか?

4

1 に答える 1

1

私の問題は、ページングクエリ中にアクティビティを変更する方法にありました。ステータスがPENDINGの最初の20ページを選択しました。次に、そのページで、それらの20のステータスをFINISHEDに設定します。次に、20PENDINGの2ページ目を取得します。この後続のクエリobvioulsyは、FINISHED(id 1-20)に設定した最初の20を無視し、id 21-40のアクティビティをページ1として扱い、ページ2(id 41-60のActivites)を選択します。

したがって、修正はページング自体を使用せず、結果を毎回最初の20(ページサイズ)に制限し、ページ<=ページの間このクエリをループすることでした。

于 2012-05-05T07:44:46.717 に答える