我正在使用Play 2.0.4 Java。有两个api,一个是从通道对象中删除成员详细信息,另一个是添加。两个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);
}
}
)
....
}
当我非常密切地调用两个请求时,我从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]