-2

Grails 2.1(HibernateとSpring)を使用して、BidServiceの次の「ナイーブ」実装で入札システムを実装しようとしましたが、レイズ条件を防ぐことができず、異なる同時ユーザーからの「重複」入札が発生します。

いくつかの情報:-BidServiceはデフォルトでトランザクションです-アイテムと入札モデルは「バージョン:false」(悲観的ロック)を使用します

class BidService{
  BidResult processBid(BidRequest bidRequest, Item item) throws BidException {
        // 1. Validation
        validateBid(bidRequest, item)   // -> throws BidException if bidRequest do not comply with bidding rules (price too low, invalid user, ...) 
       // 2. Proces Bid (we have some complex rules to process the bids too, but at the end we only place the bid
       Bid bid = placeBid(bidRequest, item)

       return bid
  }

   Bid placeBid(BidRequest bidRequest, Item item){
      // 1. Place Bid
      Bid bid = new Bid(bidRequest) // create a bid with the bidRequest values
      bid.save(flush: true, failOnError: true)

      // 2. Update Item price
      item.price = bid.value
      item.save(flush: true, failOnError: true)

      return bid      
   }
}

ただし、http: //grails.org/doc/latest/guide/services.htmlに記載されているように、 9.2スコープサービス:デフォルトでは、サービスメソッドへのアクセスは同期されないため、これらのメソッドの同時実行を妨げるものはありません。実際、サービスはシングルトンであり、同時に使用される可能性があるため、サービスに状態を格納する場合は十分に注意する必要があります。または、簡単な(そしてより良い)道を進み、サービスに状態を保存しないでください。

processBid()メソッド全体で「同期」を使用することを考えましたが、それはかなり失礼に聞こえ、活性の問題やデッドロックを引き起こす可能性があります。一方、入札を非同期で処理すると、オークションの勝ち負けに関するユーザーフィードバックを直接送信できなくなります。

この場合に使用するアドバイスやベストプラクティスはありますか?

PS:私はすでにgrails MLについて質問しましたが、それはかなり広いJava同時実行性の質問です。

4

1 に答える 1

2

サービスはステートレスであるため、同期する必要はありません。ステートになると同期が必要になります。

また、ロックを使用する必要はありません。既存の状態を変更せず、新しい行を追加するだけです。さらに、私はGORMの専門家ではversion: falseありませんが、その名前が示すとおりに楽観的ロックをオフにする必要があります。これは、悲観的ロックがアクティブになっていることを意味するものではありません。

あなたの質問から、私はあなたの問題が何であるかを理解していませんが、固有の制約はデータベースでの重複を防ぐものです。

于 2012-09-16T20:13:50.700 に答える