我有一个C#Windows IIS服务器(Windows Server 2003)应用程序连接到Linux上托管的Oracle数据库(Red Hat 5.3上的10gR2)。间歇性地,Oracle在通信信道错误上抛出ORA-3113:文件结束。这会在C#中搞砸OracleConnection对象。然后,任何尝试使用OracleConnection的新OracleCommand都会失败,说连接已经关闭。
我已经查看了此错误生成的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错误?
答案 0 :(得分: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
。
答案 1 :(得分:0)
您可以从某些PL-SQL代码手动抛出该异常(例如在触发器中)。
答案 2 :(得分:0)
您可以杀死您的会话。
alter system kill 'sid,serial#' immediate
您可以查询V$SESSION或V$MYSTAT并进行解决,但最好使用sys_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;
当然,您可以随时手动完成,这可能会更容易。
答案 3 :(得分:0)
我知道最初的问题是针对Linux上的Oracle进行系统设置。对于那些在 Windows 上运行Oracle数据库XE的人来说,有一种简单的方法可以重现这一点。
进入正在运行的服务(在控制面板\系统和安全\管理工具中找到),然后停止名为 OracleServiceXE 的进程。这也会导致ORA-03113出现。