0

私は休止状態で比較的新しいので、優しくしてください。実行時間の長いメソッド (最長 2 分) に問題があり、DB に格納されているオブジェクトのステータス フィールドの値を変更しています。以下の疑似コードは、私の問題を説明するのに役立ちます。

public foo(thing) {  
    if (thing.getStatus() == "ready") {
        thing.setStatus("finished");
        doSomethingAndTakeALongTime();
    } else {
        // Thing already has a status of finished. Send the user back a message.
    }
}

疑似コードについては、あまり説明する必要はありません。doSomethingAndTakeALongTime() を実行したいのですが、ステータスが「準備完了」の場合のみです。私の問題は、doSomethingAndTakeALongTime() が終了するまでに 2 分かかり、物のステータス フィールドへの変更が foo() を離れるまでデータベースに保持されない場合に発生します。そのため、別のユーザーがその 2 分間にリクエストを送信すると、if ステートメントは true と評価されます。

フィールドを更新してセッションを手動でフラッシュしようとしましたが、うまくいかなかったようです。私はここから何をすべきかわからないので、助けていただければ幸いです。

PS: 私の休止状態のセッションは春に管理されています。

4

2 に答える 2

2

Thread基本的に、メソッドをすぐに返すには、別の方法で実行する必要があります。それ以外の場合は、長時間実行されているタスクが終了するまで実際にブロックされます。エンティティ自体をスレッドに渡して、ステータス自体を更新できるようにすることができます。単純なを使用した基本的なキックオフの例を次に示しThreadます。

public class Task extends Thread {
    private Entity entity;
    public Task(Entity entity) {
        this.entity = entity;
    }
    public void run() {
        entity.setStatus(Status.RUNNING);
        // ...
        // Long running task here.
        // ...
        entity.setStatus(Status.FINISHED);
    }
}

public synchronized void foo(Entity entity) {
    if (entity.getStatus() == Status.READY) {
        new Task(entity).start();
    } else {
        // ...
    }
}

列挙型ではStatus、の代わりにステートメントを使用することもできます。switchif/else

    switch (entity.getStatus()) {
        case READY: 
            new Task(entity).start();
            break;
        case RUNNING:
            // It is still running .. Have patience!
            break;
        case FINISHED:
            // It is finished!
            break;
    }            

実行中のスレッドをより堅牢に制御するには、ExecutorService代わりに検討することをお勧めします。これにより、スレッドの最大数を制御し、タイムアウトを指定できます。

于 2010-05-26T22:16:49.427 に答える
0

メソッドdoSomethingAndTakeALongTime()は何をしていますか?DB操作用ですか、それとも単にビジネスロジックを実行するためですか?

DB操作を実行しておらず、問題がない場合は、statusそのメソッドを呼び出す前にオブジェクトを永続化できます。

また、DB操作を実行している場合は、それを待つ必要があります。したがって、スレッドを挿入した場合でも、そのスレッドが完了するのを待つ必要があります(これを使用thread.join()して)

重要なのは、永続化する前に、ORMオブジェクトに基づいてすべての操作を完了している必要があるということです。したがって、永続化する前に、メソッドのロジックを最適化して実行するようにしてください。

ありがとう。

于 2010-05-27T06:31:58.187 に答える