2

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]
4

0 に答える 0