ノードの階層を編集するモジュールを構築しています。これは、多くのレベルのネストされたディレクトリとファイルを持つ非常に大きなディレクトリ構造と考えることができます。階層のノードは、リレーショナル データベース テーブルに格納されます。唯一の違いは、フォルダー/ディレクトリのようなものがないことです。すべてのノードは同じ特性を持っています。したがって、ノードにはノードでもある親があります。また、ルート ノードは 1 つしかなく、ノードは親ノードを 1 つしか持てないため、ポリ階層はありません。
表の列:
node_id [bigint] null でない
名前 [nvarchar(50)]
parent_node_id [bigint]
leaf_node [bit]
目標は、ユーザーが互いに足を踏み入れることなく、1 つの階層を編集する方法を見つけることです。バージョン管理アーキテクチャを設計して競合を解決するか、何らかのロック メカニズム (悲観的または楽観的) を使用して、階層全体内の特定の親ノードの祖先 (またはサブツリー) の一部であるノードを他のユーザーが編集できないようにする必要があります。木。ロックを実行すると、エディターを使用しているすべての人が、他のユーザーの変更を確認するためにツリーを常に更新する必要があります。
気になる機能は3つだけ。マスター ツリーでノード/オブジェクトを編集できるのは、1 人のユーザーのみです。新しく作成されたサブツリーをマスター ツリーにドラッグ アンド ドロップします。マスター ツリー内のサブツリーをマスター ツリー内の別のノードにドラッグ アンド ドロップして、ドロップしたサブツリーをそのノードの子にします。
このアーキテクチャは、フォルダとファイルを管理するオペレーティング システムのアーキテクチャと何ら変わりはないと思います。何千人ものユーザーがいる場合、通常はどのように行われますか? バージョン管理を使用して複雑さを軽減するのではなく、ロックメカニズムを使用したいと思います。最善のアプローチが何であるかはわかりません。
これまでの私の計画は次のとおりです。
ノードが編集されている場合は、保存が行われ、データベースがレコードを更新しようとするまでノードをロックしないでください。データベースが変更を行ったら、ロックを解除します。データベースが変更を行っているのとまったく同じタイミングで他の誰かがレコードを編集しようとした場合、ロックされていることをユーザーに伝えないでください。データベースにレコード/ノードのロックを処理させます。
新しいサブツリーがマスター ツリーの親ノードにドラッグされている場合は、新しい親をロックします。次に、新しいレコードを挿入し、マスター ツリーの親ノードを指すようにルートの親を更新します。次に、マスター ツリーを更新するようにすべてのクライアントに通知します。したがって、ドロップが発生した後、すべてのロックはデータベース側で行われます。
既存のマスター ツリーの親ノードが既存のマスター ツリーの親ノードにドラッグされ、子ノードになる場合は、古い親 (新しい子になる) をロックし、新しい親をロックする必要があります。次に、新しい子の親ノードを更新します。次に、すべてのクライアント (すべてのユーザー) を更新し、マスター ツリーを更新します。したがって、ドロップが発生した後、すべてのロックはデータベース側で行われます。