0

我有一个 C# Windows IIS 服务器 (Windows Server 2003) 应用程序连接到托管在 Linux 上的 Oracle 数据库(Red Hat 5.3 上的 10gR2)。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();
}

我尝试在表上编写一个 PL/SQL 触发器,当我尝试将其插入表中时会引发 ORA-3113。

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)杀死服务器线程/进程

窗口示例

c:\> orakill ORACLE_SID spid

之后,您将获得ORA-3113客户端。

于 2012-09-13T19:09:18.350 回答
0

您可以从一些 PL-SQL 代码(例如在触发器中)手动抛出该异常。

于 2012-09-13T18:48:08.660 回答
0

您可以终止会话。

alter system kill 'sid,serial#' immediate

您可以查询V$SESSIONV$MYSTATsys_context并解决它,但使用USERENV命名空间可能更好。

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

我知道最初的问题是针对 Linux 上的 Oracle 系统设置。对于在Windows上运行 Oracle 数据库 XE 的其他人来说,有一种简单的方法可以重现这一点。

进入正在运行的服务(在控制面板\系统和安全\管理工具中找到)并简单地停止名为OracleServiceXE的进程。这也会导致 ORA-03113 出现。

于 2013-04-02T13:22:56.627 回答