Play 2.0.4 Java を使用しています。2 つの API があり、1 つはチャネル オブジェクトからメンバーの詳細を削除するためのもので、もう 1 つは追加するためのものです。どちらの API も Akka.future() を使用しています。同じデータベース オブジェクト (同じレコード) を変更するために両方の API が非常に密接に呼び出された場合、Play からの eBean 例外 (以下を参照) を回避するにはどうすればよいですか?
モデル オブジェクト
public class Channel extends Model {
.....
@OneToMany(cascade=CascadeType.ALL, mappedBy="channelInfo")
private Set<ChannelDetailMember> members;
public void addMemberId(String memberId) {
List<String> memberIdslList = this.getMemberIdsList();
if (!memberIdslList.contains(memberId)) {
ChannelDetailMember dMember = new ChannelDetailMember(memberId, this);
dMember.save();
membersCount++;
this.getMembers().add(dMember);
}
}
public void removeMemberId(String memberId) {
Iterator<ChannelDetailMember> iter = this.getMembers().iterator();
while (iter.hasNext()) {
ChannelDetailMember dMember = iter.next();
if (dMember.getMemberId().equals(memberId)) {
dMember.delete();
iter.remove();
membersCount--;
break;
}
}
}
}
リクエスト 1: オブジェクト チャネルのメンバー リストから memberId を削除する
public static Result removeMemberIdFromChannel(final String name, final String memberId) {
Promise<ObjectNode> promiseRemove = Akka.future(
new Callable<ObjectNode>() {
public ObjectNode call() {
Channel channel = find.where().eq("name", name).findUnique();
channel.removeMemberId(memberId);
}
}
)
.....
}
リクエスト 2: オブジェクト チャネルのメンバー リストから memberId を追加する
public static Result addMemberIdToChannel(final String name, final String memberId) {
Promise<ObjectNode> promiseRemove = Akka.future(
new Callable<ObjectNode>() {
public ObjectNode call() {
Channel channel = find.where().eq("name", name).findUnique();
channel.addMemberId(memberId);
}
}
)
....
}
2 つのリクエストが非常に接近して呼び出されたときに、Play から例外が発生しました。
[error] play - Waiting for a promise, but got an error: Data has changed. updated [0] rows sql[update channel set members_count=?, update_date=? where id=? and channel_name=? and conversation_id=? and members_count=? and created_date=? and update_date=?] bind[null]
at com.avaje.ebeaninternal.server.persist.dml.UpdateHandler.execute(UpdateHandler.java:106) ~[ebean-2.7.3.jar:na]
at com.avaje.ebeaninternal.server.persist.dml.DmlBeanPersister.update(DmlBeanPersister.java:85) ~[ebean-2.7.3.jar:na]
javax.persistence.OptimisticLockException: Data has changed. updated [0] rows sql[update channel set members_count=?, update_date=? where id=? and channel_name=? and conversation_id=? and members_count=? and created_date=? and update_date=?] bind[null]
at com.avaje.ebeaninternal.server.persist.dml.DmlBeanPersister.execute(DmlBeanPersister.java:105) ~[ebean-2.7.3.jar:na]
at com.avaje.ebeaninternal.server.persist.dml.DmlHandler.checkRowCount(DmlHandler.java:123) ~[ebean-2.7.3.jar:na]
at com.avaje.ebeaninternal.server.persist.DefaultPersistExecute.executeUpdateBean(DefaultPersistExecute.java:110) ~[ebean-2.7.3.jar:na]
at com.avaje.ebeaninternal.server.core.PersistRequestBean.executeNow(PersistRequestBean.java:531) ~[ebean-2.7.3.jar:na]