2017-08-24 25 views
2

オーチャードアプリケーションに購入オーダーのコンテンツタイプがあります。他のプロパティの中にはPurchaseOrderNumberがあります。購買発注番号は、ユーザが初めて購買発注を保存するときに割り当てられます。私はカスタムオーダーCRUD操作を実装するためのカスタムコントローラーとビューを使用します。個別のデータベーストランザクションでコンテンツアイテムを書き込み要求の書き込みに書き込む方法

私は、次の注文番号、接頭辞と詰め物が保存される会社のコンテンツタイプに添付された注文番号の定義部分を持っています。システムが次の発注番号を生成するとき、文字列を生成するためにプレフィックス(例えばPO)が次の番号(例えば123)及びパディング(例えば5)と共に使用される。 PO00123。

購入注文番号が生成されると、会社コンテンツ項目に添付された注文書定義部分に格納されている次の注文番号が増分されて保存され、ユーザーが別の注文書を作成するときに次の番号が割り当てられます。

2人のユーザーが同時に新しい注文書を作成すると、重複した注文番号が割り当てられないようにするのが私の挑戦です。

ロック(_lock){...}を使って次の番号を生成するコードをラップするISingletonDependencyを作成しようと考えていました。この方法では、複数の要求が次の番号を要求し、常に次の一意の番号を取得できます。しかし、私はこれをどのように実装するのですか?独自のデータベーストランザクションを持つIContentManagerにアクセスする方法を理解できません。

または、私はむしろ使うべきパターンがありますか?

+0

注文が作成される前に注文番号**を設定したいのですが?オーダーが作成されたときに番号を割り当ててから、ユーザーに表示するのはなぜですか?そうすれば、重複することはありません – devqon

+0

番号は、ユーザーが注文を作成したときにのみ割り当てられます。問題は、2人のユーザーが約5秒で[保存]ボタンをクリックした場合です。各ユーザが同じ発注番号で終了するのと同じ時間になる。 –

答えて

2

私はOrchard.Tasks.Locking.Services.DistributedLockServiceクラスを見て、それを理解しました。 ILifetimeScopeに依存し、ITransactionManagerとIContentManagerを解決する必要があります。

lock (_lock) { 
    using (var childLifetimeScope = _lifetimeScope.BeginLifetimeScope()) { 
    var transactionManager = childLifetimeScope.Resolve<ITransactionManager>(); 
    var contentManager = childLifetimeScope.Resolve<IContentManager>(); 
    try { 
     transactionManager.RequireNew(IsolationLevel.Serializable); 
     var contentItem = contentManager.GetLatest(contentItemId); 

     var number = CompileNewNumber(contentItem); 

     contentManager.Publish(contentItem); 
     return number; 
    } 
    catch (Exception exception) { 
     Logger.Error(exception, "Error compiling next number."); 
     transactionManager.Cancel(); 
     return ""; 
    } 
    } 
} 
関連する問題