私のケースは一貫性の問題なのだろうか...
フィールド lastAttackDate を持つエンティティ クラス Player があります。トランザクションで lastAttackDate = sysdate を設定し、そのトランザクションをコミットしてから、lastAttackDate < sysdate - 10min のプレイヤーをクエリします (簡略化されたコードを参照してください)。
private static final Logger log = Logger.getLogger(MyEndpoint.class.getName());
@ApiMethod(name = "attack")
public MyResult attack(@Named("id") Long id, User user) throws Exception, OAuthRequestException, IOException {
PersistenceManager mgr = null;
Player defender = null;
Transaction tx = null;
try {
mgr = getPersistenceManager();
tx = mgr.currentTransaction();
tx.begin();
long now = new Date().getTime();
defender = getPlayer(mgr, id);//I get player by param ID
defender.setLastAttackDate(now);
tx.commit(); //mgr.close(); mgr = getPersistenceManager();--> I tried that, it did not help
long param = now - 10*60*1000;//sysdate - 10 minutes
Query q = pm.newQuery("select from " + Player.class.getName() +" where lastAttackDate < lastAttackDateParam parameters long lastAttackDateParam");
Set<Player> result = new HashSet<Player>();
result.addAll((List<Player>) q.execute(param));
Iterator<Player> it = results.iterator();
while(it.hasNext())
{
Player p = it.next();
if (p.getLastAttackDate() >= param)
{
log.log(Level.SEVERE, "It really just gave me a result that doesn't meet the criteria");//defender (the recently updated player) falls in this category
it.remove();
}
}
}
finally {
if (tx != null && tx.isActive())
tx.rollback();
if (mgr != null)
mgr.close();
return null;
}
}
私を悩ませているのは、このクエリの結果として依然として防御者が得られることです。さらに気になるのは、結果を反復して基準を満たしているかどうかを確認すると、そうでないことがわかるということです。一貫性の問題である場合、 getLastAttackDate() は更新された値ではなく古い値を返す必要があると思いますが、正しい値、つまり最新のものを返します。私は何を間違っていますか?機能させるにはどうすればよいですか?
現時点では、結果セットを繰り返し処理し、検索基準を満たさないエントリを削除しますが、コストがかかります (読み取り、CPU 時間、再試行するための追加のクエリ)。