我們有一個HTTP端點,需要很長時間才能運行,也可以由用戶同時調用。作爲此請求的一部分,我們更新同步塊內的模型,以便其他(可能是併發的)請求獲取該更改。玩1.2.3框架 - 正確的交易方式
E.g.
MyModel m = null;
synchronized (lockObject) {
m = MyModel.findById(id);
if (m.status == PENDING) {
m.status = ACTIVE;
} else {
//render a response back to user that the operation is not allowed
}
m.save(); //Is not expected to be called unless we set m.status = ACTIVE
}
//Long running operation continues here. It can involve further changes to instance "m"
的原因同步塊是保證即使併發請求到達搭載了最新的狀態。但是,在請求完成之前,底層的JPA不會提交我的更改(m.save())。由於這是一個長時間運行的請求,因此我不希望等到請求完成,並且仍然希望確保其他調用者被通知狀態更改。我嘗試調用「m.em()。flush(); JPA.em()。getTransaction()。commit();」在m.save()之後,但是使得事務不可用於後續操作,作爲同一請求的一部分。我可以只給「JPA.em()。getTransaction()。begin();」並讓Play從此處理交易?如果不是,處理這個用例的最好方法是什麼?
UPDATE:基於響應 ,我修改了代碼如下:
MyModel m = null;
synchronized (lockObject) {
m = MyModel.findById(id);
if (m.status == PENDING) {
m.status = ACTIVE;
} else {
//render a response back to user that the operation is not allowed
}
m.save(); //Is not expected to be called unless we set m.status = ACTIVE
}
new MyModelUpdateJob(m.id).now();
而且在我的工作,我有以下行:
doJob() {
MyModel m = MyModel.findById(id);
print m.status; //This still prints the old status as-if m.save() had no effect...
}
我在想什麼?
感謝。我根據您的回覆更新了我的帖子。總之,工作似乎沒有得到行的更新,並仍然看到舊的狀態。 – Ananth 2012-02-15 08:51:32
@Ananth您是否檢查過[在異步HTTP上播放文檔](http://www.playframework.org/documentation/1.2.4/asynchronous)?在我看來,如果你還要告訴你的控制器方法你想等待工作完成,雙工設置應該可以工作。 – tmbrggmn 2012-02-15 10:21:12
對播放控制器的調用是一個事務。因此,當http請求/響應完成時,您將看到在控制器中完成的修改。在你的工作中,你看不到在控制器中完成的事情,因爲方法沒有完成。你必須重新考慮你的代碼庫。你還要照顧Dean說的話。同步塊用於商業目的不是一個好的做法,這不會擴展 – 2012-02-16 08:21:33