2

Pyramid アプリケーションを構築しようとしています。SQLAlchemy の足場から始めました。問題が発生しており、それに対処する最善の方法を考えています。私のビューの 1 つで、関連のない 2 つのテーブルから多くの行を選択する必要があります。最初のテーブルから行を選択してから 2 番目のテーブルから行を選択するまでの間に、2 番目のテーブルに行が挿入されていないことを確認する必要があります。

NodeTest、およびの 3 つのモデルがありTaskingます。と の両方NodesTestsかなりのメタデータがあります。のリストNodesと のリストを指定するとTests、 のグローバル リストをTaskings作成できます。たとえば、 「タスクを実行するには 1 つのノードが必要」と「タスクを実行するには 2 つのノードが必要」の 3 つNodesabcおよび 2 つを持つことができます。TestsPQ

その情報から、3 つTasks作成する必要があります。例えば:

  1. 「ノードaはタスクを実行する必要がありますP
  2. 「ノードbはタスクを実行する必要がありますQ
  3. 「ノードcはタスクを実行する必要がありますQ

今、私はこれに REST API を提供しようとしています。ほとんどの場合、クライアントは のリストを要求するTasksため、高速である必要があります。ただし、クライアントがNodeまたは を追加する場合がありTestます。その場合、 のリスト全体をTasks再生成する必要があります。

大まかな例を次に示します。

@view_config(route_name='list_taskings')
def list_taskings(request):
    return DBSession.Query(Tasking).all()

@view_config(route_name='add_node')
def add_node(request):
    DBSession.add(Node())
    _update_taskings()

@view_config(route_name='add_test')
def add_test(request):
    DBSession.add(Test())
    _update_taskings()

def _update_taskings():
    nodes = DBSession.query(Node).all()
    tests = DBSession.query(Test).all()

    # Process...

    Tasking.query.delete()
    for t in taskings:
        DBSession.add(t)

デフォルトの Pyramid SQLAlchemy 足場を使用しています。したがって、各リクエストは自動的にトランザクションを開始します。したがって、_update_taskingが 1 つのリクエスト (たとえばadd_node) から呼び出された場合、新しいノードが local に追加され、 allおよびinDBSessionに対してクエリを実行すると、その新しい要素が返されます。さらに、既存のものをすべて削除し、新しく計算されたものを追加することも安全です。NodesTests_update_taskingTaskings

2 つの問題があります。

  1. のリストを取得してから のリストTestsを取得するまでの間に新しい行がテーブルに追加された場合はどうなりますか? 私の実際の生産システムでは、これらの選択は互いに近接していますが、互いに隣接していません。競合状態の可能性があります。nodestests_update_taskings

  2. Taskings更新する 2 つのリクエストが互いに上書きしないようにするにはどうすればよいですか? たとえば、既存のシステムに oneNodeと oneがあるとしTestます。1 つは a を追加する要求で、もう 1 つは a を追加する要求NodeですTest。問題 #1 が問題ではなく、各リクエストの select のペアが「データベース内の時間の単一のインスタンス」を表していることがわかっていたとしても、1 つのリクエストが他のリクエストをオーバーライドするという問題がまだ残っています。最初のリクエストが now two Nodesand oneTestで最初に終了した場合、2 番目のリクエストはまだ古いデータを選択し (潜在的に)、Taskingswith one Nodeand twoのリストを生成しTestsます。

それで、これに対処する最善の方法は何ですか?開発には SQLite を使用し、本番環境では PostgreSQL を使用していますが、データベースに依存しないソリューションが必要です。他のアプリケーションがこのデータベースにアクセスする心配はありません。私の REST API が唯一のアクセス メカニズムになります。データベースを変更するリクエスト ( aNodeまたは aを追加Test) をロックする必要がありますか? どうにかしてデータベースをロックする必要がありますか?

助けてくれてありがとう!

4

1 に答える 1