Playframework 1.2。* EventStream,@ PostUpdate和@PostPersist

时间:2014-10-14 08:07:16

标签: jpa playframework playframework-1.x

我有一个应用程序,其中一些请求允许修改某些实体和一个阻塞的请求,直到执行修改(通知更改客户端)

我做了以下事情:

@Entity
class TheEntity extends Model {

    public static Collection<TheEntity> getLastEntities(after) {
       //finds the entities where the `lastUpdateTimestamp` is greater than `after`
       return TheEntity.find("byLastUpdateTimestampGreaterThan", after).fetch();
    }

    @PostUpdate
    @PostPersist
    private void notifyChannel() {
        lastUpdateTimestamp = System.currentTime();
        Job asyncNotifier = new Job() {
            @Override
            public void doJob() throws Exception {
                //we manage the updates. the message channel trigs the channel
                MyChannel.publish(AcEvent.this);
            }

        };
        asyncNotifier.now();
    }
}

现在,我有一个监听频道的控制器

public static void listenMessageUpdate(Long after,Long blockDuration) {
    Collection<TheEntity> evts = MyChannel.getLast(after);
    if (evts.isEmpty()) {
        Timeout timeout = F.Timeout(blockDuration*1000);
        Promise<TheEntity> nextFlt = MyChannel.nextEvent();
        Either<Timeout, TheEntity> await = await(F.Promise.waitEither(
                timeout, nextFlt));

        evts = TheEntity.getLastEntities(after);
    }
    renderJSON(TheEntity.toJson(evts));
}

实际上,TheEntity.getLastEntities(之后)不会在PROD模式下返回最近修改或创建的元素。

经过调查,在通知事件流时未提交事务,因此,实体在数据库中不是最新的

每次实体修改时收到通知的最佳做法是什么?

1 个答案:

答案 0 :(得分:0)

问题是行MyChannel.publish(AcEvent.this);

实际上,AcEvent.this是会话+事务中的实体。 listenMessageUpdate属于其他会话+事务,因此,访问不是确定性的。解决方案是将发布的内容传递给非实体。不能既不是ID,也不能刷新(listenMessageUpdate执行时事务未提交)。

我们必须传递一个包含有用字段的IO结构