質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.50%

  • Python

    11716questions

    Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

  • Django

    1609questions

    DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

pythonのDjangoで、変数の値を共有する方法

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 1,396

TakaSasa

score 4

python3系で、Djangoを用いたWEBアプリを開発しています。

その中で、キャッシュの仕組みを作るところで悩んでいます。
下記の場合のそれぞれで、変数の値を共有する方法を教えていただけませんでしょうか。

<調べて分かったこと>
関数(def ~)の外側で宣言した変数は、各関数で値を共有出来る。
ただし、関数内でglabalを付けて変数を呼び出さないと、変更できない。

<調べても分からなかったこと>
1.WEBで、ユーザーAとユーザーBで変数の値を共有する方法。
ユーザーAが呼び出した関数で変数が変更されると、次にユーザーBがその変数にアクセスしたときに、
変更された値を参照したい。
2.上記は、同じページを前提としていますが、異なるページ間でも変数の共有を行いたいです。
具体的には、DBから取得したマスタデータをキャッシュしたく、
アプリを立ち上げで1度だけDBにアクセスすれば、後はその値を変数にもっておき、
次からはどのユーザーがどのページから実行した関数でも、キャッシュを利用できるようにしたいです。

また、1と2で、値の更新の衝突が起こりうる場合に、それを防ぐような工夫は何かありませんでしょうか。

よろしくお願いいたします。

<追記>
2は下記のようなイメージです。
http://www.atmarkit.co.jp/fdotnet/dotnettips/122globalobj/globalobj.html

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+1

1.WEBで、ユーザーAとユーザーBで変数の値を共有する方法。
ユーザーAが呼び出した関数で変数が変更されると、次にユーザーBがその変数にアクセスしたときに、変更された値を参照したい。

通常はデータベースに記録すると思いますが、どうしても「キャッシュの仕組み」でやろうとするのであれば、Djangoのキャッシュフレームワークを使えばできそうです。
https://docs.djangoproject.com/en/1.11/topics/cache/

2.上記は、同じページを前提としていますが、異なるページ間でも変数の共有を行いたいです。
具体的には、DBから取得したマスタデータをキャッシュしたく、アプリを立ち上げで1度だけDBにアクセスすれば、後はその値を変数にもっておき、次からはどのユーザーがどのページから実行した関数でも、キャッシュを利用できるようにしたいです。

これもDjangoのキャッシュフレームワークで解決できますね。

また、1と2で、値の更新の衝突が起こりうる場合に、それを防ぐような工夫は何かありませんでしょうか。

通常はデータベースのトランザクションを使います。
データベース以外の(キャッシュなどの)方法で行う場合、 セマフォスピンロッククリティカルセクション といった仕組みをキャッシュか何かの、共有された領域を使って実装する必要があります。

簡単に説明すると、キャッシュに「これから更新するフラグ」を用意して、このフラグが立ってるときは別の処理はフラグを立てられなくする、という考え方です。

しかし、書かれている内容からすると、必要なのはデータベースのトランザクションのように思えるので、先にそちらを検討した方が良いかもしれません。

なお、キャッシュについては、以下の2つの回答も参照してみてください。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/07/30 22:27

    早速ありがとうございます。
    DBへの値の保存が一般的のようですね。
    追記させていただきましたが、ASP.NETにおけるGlobalやApplicationオブジェクトのようなものがあれば、大変助かりました。
    pythonやDjangoでは、同じようなことは出来なさげですね。。。

    キャンセル

  • 2017/07/30 22:45

    そこまでフレームワーク化されたものはDjango標準にはなさそうですね。

    キャンセル

0

キャッシュが必要ということは、毎分1万PVとかのオーダーでリクエストが突っ込んでくる高負荷なWebアプリを作っているんでしょうか?

そもそも変数をキャッシュとして使うのはおすすめできません。マルチプロセスで Django が動いている場合はそもそもメモリ空間が全く別なので互いにキャッシュの更新を検出できませんし、マルチスレッドでも考え無しに同時書き換えした場合にデータが容易に破壊してしまいます。

一般的には高速なキャッシュサーバーを別に立てて利用することが多いようです。Django の公式リファレンス: Django のキャッシュフレームワーク — Django 1.4 documentation にあるように、Memcached をバックエンドとして 低水準のキャッシュAPI を使うのがよい落としどころだと思います。

またキャッシュサーバーは基本的に更新の競合を防ぐ仕組みを持ちません(だから速いんです)。マスターデータは RDBMS (MySQL, PostgreSQL など)にあると思いますので RDBMS のロック機能を使わせてもらえばよいと思います。具体的にはキャッシュミス時や更新時に排他ロックをかけてマスターデータの読み書きを行いつつ、その間にキャッシュサーバーのデータを更新するようにすれば競合が回避できます。ただ万が一トランザクションが失敗してロールバックが走ると、マスターデータは前のままでキャッシュは失敗したデータと不整合が起きます。更新がガシガシ走るようなパラメーターはそもそもキャッシュの効果は薄いですし、本当にキャッシュが必要なのか慎重に検討すべきだと思います。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

同じタグがついた質問を見る

  • Python

    11716questions

    Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

  • Django

    1609questions

    DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。