4

私はオークションシステムに取り組んでいますが、影響を受けないようにしようとしている問題の1つは、2人が同じアイテムにまったく同時に入札するという状況です。

これを行うには、テーブルをロックし、現在のアイテムの最高入札額を取得し、入力された入札額がその入札額よりも大きいことを確認し、テーブルに新しい入札エントリを追加してから、テーブルのロックを解除する必要があります。

これをロックして、最高入札額を確認してから新しい入札単価をテーブルに挿入するまでの間に2番目のウェブサーバーが入札単価の挿入をトリガーしないようにする必要があります。これによりデータの問題が発生します。

Linq-to-sqlを使用してこれを実現するにはどうすればよいですか?

注:transactionscopesがこれを実行できるかどうかはわかりませんが、webfarmの設定により分散トランザクションがトリガーされる傾向があり、分散トランザクションを使用できないため、使用できません。

4

3 に答える 3

2

純粋なLinqでソリューションを実装するには、いくつかの障害があるようです。

  • あなたは間違いなくテーブルロックを避けるべきです

テーブルロックを使用すると、1回の入札の処理中に複数のアイテムに入札できなくなり、パフォーマンスが大幅に低下します。

  • LinqtoSQLは悲観的なロックをサポートしていないようです

SOに関する他の回答で述べられているように。

コードにトランザクションを含めることができない場合は、次の手順をお勧めします。

  • 操作のGUIDを生成する
  • guidを使用してアイテムのレコードを疑似ロックします。

    UPDATE Items SET LockingGuid = @guid 
    WHERE ItemId = @ItemId and LockingGuid IS NULL
    
    SELECT @recordsaffected = @@ROWCOUNT
    
  • @@ rowcount == 1の場合、ロックは成功しました

  • 入札操作を実行します
  • レコードを更新してLockingGuid=NULLに戻します

  • ロックが失敗した場合は、.Netクライアントに失敗を発生させるか、WAITFORを使用してビジーウェイトします。

おそらく、ロックが発生したタイムスタンプを格納する日時列を追加し、孤立したロックをクリーンアップすることによって、死にかけているプロセスや失敗したプロセスによってアイテムレコードが無期限にロックされないように、適切な例外処理を実装する必要があります。

アーキテクチャで個別のバックエンド操作が許可されている場合は、そのような入札操作を処理するための外観とCQRSおよびイベントソーシングが必要になる場合があります。

于 2012-07-07T23:11:59.363 に答える
1

この処理が発生したときに、別のテーブルを使用して情報を格納できます。たとえば、2番目のテーブルは次のようになります。

テーブル名:
ItemProcessing

列:
ItemId(int)
ProcessingToken(guid)

プロセスが現在の入札を確認する場合、アイテムのIDとトークン/GUIDをItemProcessingテーブルに書き込みます。これは、このアイテムが現在検査中であることを他のプロセスに通知します。このアイテムのItemProcessingテーブルにすでに行がある場合、他のプロセスは待機または中止する必要があります。元のプロセスが完了すると、トークンが削除されるか(nullに設定されます)、またはItemProcessingから行が完全に削除されます。その後、他のプロセスは、そのアイテムを処理できることを認識します。

もちろん、両方のプロセスがこの処理テーブルに同時に書き込まないようにする方法が必要になります。これは、ProcessingTokenがnullであるこのテーブルに挿入することで実現できます。別のテーブルがプロセスに勝った場合、ProcessingTokenが存在するため、2番目のプロセスは挿入できません。

完全な解決策ではありませんが、詳細には、それが基本的な考え方です。

于 2012-07-07T22:25:17.150 に答える
1

手動でトランザクションを開始し、そのトランザクションをDataContextに渡すことができます。

http://geekswithblogs.net/robp/archive/2009/04/02/your-own-transactions-with-linq-to-sql.aspx

分散トランザクションへの不要なエスカレーションを回避するために、接続の開閉を手動で制御することも必要だと思います。DataContextは実際には独自の方法で取得し、2つの接続を開こうとすることがあるため、分散トランザクションへの昇格が発生するようです。

于 2012-07-07T23:21:45.217 に答える