0

Linux (Red Hat 5.3 上の 10gR2) でホストされている Oracle データベースに接続する C# Windows IIS サーバー (Windows Server 2003) アプリケーションがあります。断続的に、Oracle は ORA-3113: end-of-file on communication channel エラーをスローします。これにより、C# の OracleConnection オブジェクトが台無しになります。次に、OracleConnection を使用しようとする新しい OracleCommands はすべて、接続が閉じられたと言って失敗します。

このエラーによって生成された Oracle トレース ファイルを確認し、問題をネットワーク ハードウェアの障害に切り分け、修正に取り組んでいます。

ただし、C# コードをより堅牢にし、その接続オブジェクトを閉じて使用しないことで、このエラーに適切に応答する必要があります。C# で例外をキャッチするのは簡単ですが、開発環境でネットワークの問題を再現して、コードが機能し、その後クリーンアップされることを証明することはできません。

try
{
  oracleCommand.ExecuteNonQuery();
}
catch(OracleException exception)
{
  if(exception.Code == 3113)
    CloseAndCleanup();
}

テーブルに INSERT しようとすると ORA-3113 をスローする PL/SQL トリガーをテーブルにコーディングしようとしました。

CREATE OR REPLACE TRIGGER SCHEMA.TABLE
BEFORE DELETE OR INSERT OR UPDATE
ON SCHEMA.TABLE
FOR EACH ROW
DECLARE
  CONNECTION_LOST_CONTACT   EXCEPTION;
  PRAGMA EXCEPTION_INIT (CONNECTION_LOST_CONTACT, -3113);
BEGIN
  RAISE CONNECTION_LOST_CONTACT;
END;

これは正しいエラーをスローしますが、C# の OracleConnection オブジェクトを破損しません。コマンドを OracleConnection に送信することはできますが、動作します。

ORA-3113 エラーを正確にシミュレートするにはどうすればよいですか?

4

4 に答える 4

5

ORA-3113クライアントに割り当てられたサーバー プロセス/スレッドが予期せず終了したか、故意に終了したことを意味します。ORA-3113サーバープロセス/スレッドを手動で強制終了すると、エラーが発生する可能性があります。セッションを強制終了しても、そのエラーは発生しません。

そのエラーを再現するには、次の手順を実行できます。

1) セッションに関連付けられているサーバー プロセス/スレッドを特定する

select p.spid  -- process ID
     , s.program  -- your oracle client
  from v$process p
  join v$session s
    on p.addr = s.paddr 

サーバー側

2) orakill(Windows) またはkill -9 ..(Linux) を使用して、サーバー スレッド/プロセスを強制終了します。

Windows の例

c:\> orakill ORACLE_SID spid

その後ORA-3113、クライアント側で を取得します。

于 2012-09-13T19:09:18.350 に答える
0

あなたはあなたのセッションを殺すことができます。

alter system kill 'sid,serial#' immediate

V $ SESSION、またはV $ MYSTATをクエリして解決することもできますがsys_contextUSERENV名前空間を使用する方がおそらく良いでしょう。

select sys_context('USERENV','SESSIONID') from dual

現在のセッションID(sid)を取得し、V$SESSIONをクエリしてを取得できますserial#

この手順は、それを実行したセッションを強制終了します。

create or replace procedure kill_my_session is

   l_sid v$session.sid%type;
   l_serial v$session.serial#%type;

begin

   select sid, serial#
     into l_sid, l_serial
     from v$session
    where sid = (select sys_context('USERENV','SESSIONID') from dual)
          ;

   execute immediate 'alter system kill session '''|| l_sid  
                       || ',' || l_serial# || ''' immediate';

end;

もちろん、いつでも手動で行うことができます。これは簡単かもしれません。

于 2012-09-13T18:57:23.130 に答える
0

その例外は、一部の PL-SQL コード (トリガーなど) から手動でスローできます。

于 2012-09-13T18:48:08.660 に答える