0

我对休眠比较陌生,所以请温柔一点。我在长时间运行的方法(约 2 分钟长)和更改存储在数据库中的对象上的状态字段的值时遇到问题。下面的伪代码应该有助于解释我的问题。

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:我的休眠会话由 spring 管理。

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 {
        // ...
    }
}

使用Statusin枚举,您甚至可以使用switch语句而不是if/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()在做什么?是用于数据库操作还是只是执行一些业务逻辑?

如果它没有做任何数据库操作,并且你得到了你的status罚款,那么你可以在调用该方法之前保留该对象。

如果它在做一些数据库操作,那么你需要等待它。因此,即使您放入线程,您也需要等待该线程完成(使用thread.join()我们可以做到这一点)

问题是,在你坚持之前,你必须已经完成了基于你的 ORM 对象的所有操作,对吧?因此,请尝试优化该方法的逻辑以使其在您坚持之前执行。

谢谢。

于 2010-05-27T06:31:58.187 回答