2017-07-19 15 views
1

すべてのデータベース接続を閉じていない「接続リーク」があることが判明したC#Oracleクライアントで作成されたプログラムで、開いている接続が多すぎるため、しばらくしてもデータベースに接続できなくなります。Oracleの接続リークを検出する最善の方法は?

私は、次のヘルパー関数(かなり広大)を書いた:ここ

 private static int tryFindConnCount(){ 
      var connstk = new Stack<Oracle.ManagedDataAccess.Client.OracleConnection>(); 
      try 
      { 
       for (var i = 0; i < 10000; ++i) 
       { 
        var conn = new Oracle.ManagedDataAccess.Client.OracleConnection(
         myDatabaseConnection); 
        conn.Open(); 
        connstk.Push(conn); 
       }     
      } 
      catch(Exception e) 
      { 
       foreach (var conn in connstk) 
       { 
        conn.Close(); 
       } 

      } 
      return connstk.Count; 
     } 

は、上記を使用してテストケースのコードです:

  var co = tryFindConnCount(); 
      CodeThatMayLeakConnection(); 
      var cn = tryFindConnCount(); 

      Assert.That(cn, Is.EqaulTo(co)); 

それは私が少なくとも一つのケースを識別助けました接続リークが発生しています。

tryFindConnCountの問題は、本番環境では使用しないことです。そして私は、同じ価値をもっと安く得るための方法があるべきだと思います。

コードでこれを実行すると、プロダクションでこの値を監視できますか?

+1

Oracle dbを問い合せて、そのプログラムから発生した接続の総接続数を取得できます。例:select count(*) from gv $ session machine = 'XXXXX' 、username = 'YYYYY' 、program = 'ZZZZZ'; – ivanzg

+0

"server.123.local.com"、接続がデータベースに入るDBユーザ名、そしておそらく "clientprogram1"のようなプログラム名のような、それらの接続を一意に識別する特定の値が必要です。 "または他の何らかの属性です。 – ivanzg

答えて

2

接続が閉じていない場所を見つけることは難しい作業です。

プログラムを終了して接続を閉じるのを忘れた場合、実行された最後のsqlはv $ session(RACの場合はgv $ session)の列SQL_IDに格納されます。アイドル/デッドセッションでv $ sessionを検索することができます。その後、v $ sqlを使用して、最後に何が行われたかについてさらに詳しく説明するSQLテキストを見つけることができます。これにより、コード内のどこを検索するのかを知ることができます。

1

"gv $ session"ビューでOracle DBに問い合せると、必要な情報を取得できます。このビューのクエリでは、このプログラムからの接続数を10〜15分ごとに定期的に監視できます。以下

例クエリ:

select count(*) 
from gv$session 
where machine = 'XXXXX' 
and username = 'YYYYY' 
and program = 'ZZZZZ'; 

あなたが唯一の一意の接続が由来する例えば、マシンのようなこれらの接続を識別する値を必要としています。

また、クエリは非常に軽く、パフォーマンスオーバーヘッドを追加しません。

関連する問題