2009-12-01 9 views

答えて

6

私は接続オブジェクト自体を共有しないでください。新しい接続を作成し、ADO.netが接続プーリングを処理できるようにします。

+0

私は同意しがちですが、データベースサーバは接続プールを管理するように設計されています。そうするように設計されている。 –

10

通常、接続はスレッドセーフではありません(SqlConnection、MySqlConnection、OracleConnectionは特にスレッドセーフではありません)。

スレッド間の接続を共有しないでください。

0

非常に、非常に、悪い考えで(ほとんど)誰もそれをしないので、野生にサンプルコードはありません。むしろ彼らを解雇よりも、私は接続へのアクセスを同期するために役立つDbCommandを包むだろう、問題の実際のパラメータに対応するため

3

場合、あなたは絶対に持っている唯一の場合)。

public class SyncedDbCommand : DbCommand 
{ 
    private DbCommand _cmd; 
    private object _sync; 

    public SyncedDbCommand(DbCommand cmd, object sync) 
    { 
     _cmd = cmd; 
     _sync = sync; 
    } 

    // omitted basic proxy method overrides 

    protected override DbDataReader ExecuteDbDataReader(CommandBehavior behavior) 
    { 
     Monitor.Enter(_sync); 
     return _cmd.ExecuteReader(); 
    } 

    public override int ExecuteNonQuery() 
    { 
     Monitor.Enter(_sync); 
     return _cmd.ExecuteNonQuery(); 
    } 

    public override object ExecuteScalar() 
    { 
     Monitor.Enter(_sync); 
     return _cmd.ExecuteScalar(); 
    } 

    protected override void Dispose(bool disposing) 
    { 
     if (disposing) 
     { 
      Monitor.Exit(_sync); 
     } 
     base.Dispose(disposing); 
    } 
} 

サンプルを使用するには、接続のすべての使用で共有され、実際のDbCommandなどいくつかのオブジェクトインスタンスとそれをインスタンス化する必要があります。最も単純な使い方では、接続オブジェクト自体をロックオブジェクトとして渡すことさえできます。インスタンス化はusingステートメントで行われる必要があります。これは、あなたの使用要件が何であるか、そしてクラスとロックがどのように機能するかを正確に知ることから免れません。

スレッド間で接続の使用状況を同期する必要があります。これを行う方法の1つが上記の方法です。

+1

これを絶対にしないでください。これを行う理由がなく、アプリケーションのパフォーマンスに影響します。上記の応答状態のように接続プーリングを使用します。 –

+1

「いい理由はない?彼のコードのアーキテクチャを知らなければ、あなたはそれをどのように主張できますか?接続の共有に関しては、MSDTCに昇格せずにトランザクションを有効にする方法としてよく知られています。これは大きなパフォーマンス上の利点です。それにもかかわらず、最初から始めて、当然のことながら私の答えに記載されているアプローチは助言しません。しかし、質問者を尊重し、彼の質問*の詳細に答えることは、これが私のお勧めです。 –

+0

まだ悟りを待っています... –

関連する問題