播放2.0多个Akka期货来修改相同的数据库记录

时间:2013-02-07 03:51:29

标签: playframework-2.0 akka ebean

我正在使用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]

0 个答案:

没有答案