[Oracle]ORA-12516 TNS: リスナーは、一致するプロトコル・スタックが使用可能なハンドラを検出できませんでした

[Oracle]ORA-12516 TNS: リスナーは、一致するプロトコル・スタックが使用可能なハンドラを検出できませんでした

[ORA-12516] TNS: リスナーは、一致するプロトコル・スタックが使用可能なハンドラを検出できませんでした

Oracleサーバとの接続がきちんと閉じられなかったために発生するエラーらしい。Enterprise Managerなどでセッション情報をみるとよくわかる。
プログラムで接続を閉じているか確認するとよい。

例えば:
cn.Open()
Dim rdr As Oracle.DataAccess.Client.OracleDataReader = cmd.ExecuteReader
If rdr.Read = False Then Exit Sub
<中略>
rdr.Close()
cn.Close()
rdr = Nothing
cn = Nothing

ということをやっていないだろうか?(赤に注目)

Exit Subしてしまうと続きのClose()が実行されません。「Subプロシージャーを抜けるのだから暗黙的に接続は閉じられるだろう」と思っていたら間違いのようなんです。ORA-12516 エラーで怒られます。Close()メソッドがどんな時にも最後はきっちり実行されるように調整しましょう。

cn.Open()

Dim rdr As Oracle.DataAccess.Client.OracleDataReader = cmd.ExecuteReader

If rdr.Read = False Then

‘該当なし
rdr.Close()

Else
<中略>
End If

rdr.Close()
cn.Close()
rdr = Nothing
cn = Nothing

と、Close()が実行されるようにいたしましょう。

セッションを調べるSQL

SELECT RESOURCE_NAME リソース名, CURRENT_UTILIZATION 現在数, MAX_UTILIZATION 最大数, LIMIT_VALUE 上限FROM V$RESOURCE_LIMITWHERE RESOURCE_NAME IN ('processes','sessions');
SELECT 
   S.machine,
   TO_CHAR(S.LOGON_TIME, 'YYYY/MM/DD HH24:MI:SS') LOGON_TIME,
   S.sid,
   S.serial#,
   P.PID ORACLE_PID,
   P.SPID OS_PID,
   S.STATUS,
   S.USERNAME ORACLE_USER,
   S.OSUSER OS_USER,
   S.TERMINAL,
   S.PROGRAM
FROM 
   V$PROCESS P
       LEFT OUTER JOIN V$SESSION S ON P.ADDR = S.PADDR
WHERE
    P.BACKGROUND IS NULL AND P.PID > 1
ORDER BY 
    S.machine, 
    TO_CHAR(S.LOGON_TIME, 'YYYY/MM/DD HH24:MI:SS');

上限を増やしたい場合

alter system set processes = 100 scope=spfile;
alter system set sessions = 115 scope=spfile;

セッション数は、プロセス数*1.1+5 とするそうです。
上記の変更後、サービスの再起動

解決しましたら、いいね か ツイート をお願いします

コメントする