2

次のような Django (1.4.2) データ モデルがあります。

class CoreData(models.Model):
    cdid = models.AutoField(primary_key=True,editable=False)
    atr1 = # whatever
    atr2 = # whatever

class EnvironData(models.Model):
    cdid = models.ForeignKey(CoreData)
    # etc

class TransactionData(models.Model):
    edid = models.ForeignKey(EnvironData)
    # etc

etcトランザクション データを更新するアトミック トランザクションが必要です。

tdo = TransactionData.objects.select_for_update().get(etc=criteria)
# process transaction
# modify tdo object
tdo.save()

ここまでは順調ですね。ただし、 の過程でprocess transaction、 と を確認する必要がCoreData.atr1ありCoreData.atr2ます。

それらにアクセスするtdo.edid.cdid.atr{1,2}と、Django が不足しているデータを取得するため、追加の読み取り DB クエリが発生することを理解しています。(正直に言うと、それが 1 つだけであると 100% 確信しているわけではありません。また、2 つまたは 6 つになる可能性もありますが、私はそれを疑っています。)

一方、 I will と組み合わせるselect_related()と、select_for_update()ロックする必要のない (そしてすべきではない) データをロックするだけでなく、 のオーバーヘッドも作成されますtdo.save()

3 番目のアプローチは、( とは無関係のtdo) 独立したクエリを介してデータをフェッチすることselect_related()です。さらに、それは使用できますvalues()

この最後のアプローチが最も効率的だと思います。これは、既に as を持っているEnvironDataオブジェクトからクエリを開始できるためです。edidtdo.edid_id

私の見解は正当ですか?もっと良い方法はありますか?

更新:個別にアクセスすることはまったく問題tdo.edid.cdid.atr{1,2}ありません。トランザクション中に変更される可能性さえあります。これらは互いに独立しており、トランザクション全体で値を維持する必要がないためです。(ありがとう@Uszy Wieloryba)

4

1 に答える 1

0

およびに# process transaction依存している場合は、おそらくそれらをロックする必要があります。CoreData.atr1CoreData.atr2

于 2013-03-15T09:28:36.233 に答える