2011-01-01 5 views
0

は、私は、彼らがこのようなデータアクセス層を持っているコードを見て数十万人の同時ユーザーがいるようなFacebookのようなアプリケーションの場合は、以前のユーザーがデータベースを終了するまで各ユーザーの作業をブロックしますか?Updateメソッドの場合は、データベースのロック時にスレッドをロックすると便利ですエンジンはすでにデータベースサーバーレベルで並行性を管理していますか? "純C#のロック文は

次に、ロックをGetCustomersメソッドとUpdateCustomerメソッドに移動することについて考え始めましたが、もう一度考えてみてください。「まったく役に立ちますか?」 1月3日に

編集:

あなたはすべての権利だ、私は「でGetInstance」方式で「静的」キーワードを逃しました。

Antoher thing:同じデータアクセスクラスで別のスレッドが動作していた場合、スレッドは_mutex変数にアクセスできないと考えました。つまり、_mutex変数がlockステートメントの内部から返されているため、スレッドは_mutexにアクセスすることができませんでした。次の文に達した。

return CustomerDA.GetInstance().GetCustomer();

いくつかのトレースを行った後、私は私が間違った仮定を作っていた実現します。間違った前提をしていることを確認してください。

So ...データアクセスレイヤーに(INSERT、UPDATE、DELETEの場合でも)ロックステートメントが不要で、DataAccessのメソッドが静的メソッドかインスタンスメソッドかどうかは関係ありませんか?

おかげで再び...あなたのコメントは、そのコードでロックが完全に無意味です

+2

このコードを見た場合は、どこにも戻ってこないでください。これは単に悪いコードです。それを無視します。 –

+1

私はこのコードを書いた人は、CustomerDAのシングルトンを持つことを意図していたと思います。 _mutexは読み取り専用であるため、GetInstance()のロックは実際には必要ありません。 GetCustomer()およびUpdateCustomer()でロックが存在しないため、SQL文を実行しているときにブロックされません。 –

答えて

1

私にはとても便利です。それは変更されない値を返すコードをロックするので、そこにロックされる理由はありません。コード内のロックの目的は、オブジェクトをシングルトンにすることですが、遅延初期化を使用しないので、ロックはまったく必要ありません。

データアクセス層をシングルトンにすることは本当に悪い考えです。つまり、一度に1つのスレッドしかデータベースにアクセスできません。また、クラス内のメソッドはロックを使用して、一度に1つのスレッドしかデータベースにアクセスしないようにするか、コードが正しく動作しないようにする必要があります。

代わりに、各スレッドは、データベースへの独自の接続で、データアクセスレイヤーの独自のインスタンスを取得する必要があります。そうすれば、データベースは並行性の問題を処理し、theadsはロックをまったく行う必要はありません。

+0

私はこれについて多くのことに同意できないと思います。かなり前提があります。 DALのシングルトンは、複数のスレッドの同時接続を許可するために接続プールを使用できないことを意味しません。コードは正しく表記されていません。 GetInstance()は静的である必要がありますが、静的ではありません。彼らは、ロックではデータベースへの1人のユーザーのアクセスしか許可されないと考えていました。あるいは、これまでに1つのインスタンスしか作成されていないことを確認するためにDouble-Checked Lockingの実装が誤っていました。 –

+0

@Andrew Finnell:はい、接続プールを持つシングルトンクラスも動作しますが、質問内の説明からは現在のようなものはないように聞こえません。 – Guffa

0

ロックを必要な場所に設定して、同時アクセスが発生する場所を設定します。本当に必要なだけ多くのコードをロック/クリティカルセクションに入れてください。

GetInstanceは静的であってはいけませんか?

以下の擬似コードは、でGetInstanceの動作について説明:

  1. LOCK
  2. rvalに= _mutex
  3. UNLOCK
  4. 戻りrvalに

_mutexが非指す、読み取り専用でありますnullオブジェクトなので、変更することはできません。なぜロックしますか?

データベースで並行性の管理が提供されているが、データを待っている間に自分のドメインで同じデータを2つのスレッドで同時に作成するスレッドを2つ作成すると、データベースはどのように役立ちますか?

+0

答えの最後の部分はどういう意味ですか?(2つのスレッドが同じデータを同時に書き込んでいると、データベースはどのように役立ちますか?)だから、私がメソッドレベルにロックを取るのは良い考えですか? "public int UpdateCustomer(){lock {//ここで何らかのコード}}" –

+0

このように考えることはありません: "私は常にここに物事をロックしています"。たとえば、メモリのスペア目的のためにデータベースへの接続を1つだけ使用する場合は、その接続を使用しているステートメントのみをロックする必要があります。できるだけ深い機能レベルにロックを落とし、同じ時間に実行できるステートメントをロックしないでください。 * /}/*ローカル計算* //}} " – ch0kee

+0

"グローバル変数を使用し、グローバルオブジェクトのスレッドセーフでない関数を呼び出すなど、だから一般的には、可能な限り狭いロック!もしあなたがもっと深く行くことができないと思うなら、どのステートメントがその関数呼び出しに干渉を引き起こすか自問してください。その機能の中に入り、繰り返す。 (file.write(a)のようなものになり、ライブラリに書き込む)、もっと狭くすることはできません。あなたはポイントを参照してください?これはいくつかのデッドロックを避けるための良い戦術です。すぐにロックされたオブジェクトをリリースするので、誰も不要なロックを待つ必要はありません)。この3つの事柄は互いに厳密に従わなければなりません:1)LOCK 2)GET_DATA_FROM_LOCKED 3)UNLOCK_IMMEDIATELY – ch0kee

関連する問題