2

私はDjangoのPythonでMySQLdbモジュールでMySQLを使用しています。

この場合、オートコミット モードで実行しています (そして、Django の transaction.is_managed() は実際には False を返します)。

データベースとやり取りするプロセスがいくつかあります。

Task.objects.all() を使用して、1 つのプロセスですべての Task モデルをフェッチします。

次に、別のプロセスがタスク モデルを追加します (データベース管理アプリケーションで確認できます)。

最初のプロセスで Task.objects.all() を呼び出しても、何も表示されません。しかし、connection._commit() を呼び出してから Task.objects.all() を呼び出すと、新しいタスクが表示されます。

私の質問は次のとおりです。接続レベルでキャッシュが含まれていますか? そして、それは正常な動作ですか(私には思えません)?

4

1 に答える 1

1

これは確かに自動コミット/テーブルロックに関連しているようです。

mysqldb が dbapi2 仕様を実装している場合、おそらく 1 つの連続したトランザクションとして接続が実行されます。あなたが言うとき: 'running in autocommit mode': MySQL 自体のことですか、それとも mysqldb モジュールのことですか? それともジャンゴ?

断続的にコミットしないと、取得している動作が完全に説明されます。

i) mysqldb で 1 つのトランザクションとして実装された接続 (デフォルトでは、おそらく)

ii)必要な場合にのみ接続を開いたり閉じたりするのではなく、1 つ (または複数) の永続的なデータベース接続を (再) 使用します (私の推測では、Django アーキテクチャが継承されている可能性があります)。

ii)選択 (「読み取り」) により、テーブルで「単純な読み取りロック」が発生します (つまり、他の接続はこのテーブルを「読み取る」ことができますが、「データを書き込む」必要がある接続は、このロックによってブロックされるため、(すぐに) できません)。このテーブルで「排他的ロック」(「書き込み用」に必要) を取得できないため、書き込みは無期限に延期されます (書き込み用のテーブルで (短い) 排他的ロックを取得できるまで - 接続を閉じるか、手動でコミットするとき) .

あなたの場合、私は次のことを行います:

  • 上記のシナリオで、データベースにどのテーブル ロックがかかっているかを確認します。
  • ここで Django とトランザクションについて読んでください。簡単なスキムは、標準の Django 機能を使用すると暗黙的にコミットが発生することを示唆しています。これは、手作りの SQL を送信してもおそらく送信されないことを意味します (挿入、更新...)。
于 2009-06-04T18:54:12.273 に答える