0

使用 Oracle.ManagedDataAccess.Client,以下 VB.NET 行会引发内部异常:

Dim conn As New OracleConnection(connStr)
conn.ConnectionString = "Data Source=(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = orcl))); User id=username; Password=password"
conn.Open()

conn.Open 语句成功但抛出以下异常:

A first chance exception of type 'System.Net.Sockets.SocketException' occurred in System.dll

更重要的是,打开第一个连接需要 1.5 秒。

如果我关闭连接并打开一个新连接,则没有问题。

我对非托管 Oracle 数据提供者没有这样的问题,第一次连接将在几分之一秒内完成。如果我连接到 Oracle 11g 或 12c 数据库服务器,这没有什么区别,因此看起来数据提供者是罪魁祸首。

数据提供者是否尝试了一些失败的东西,之后它在会话的其余部分默认为其他东西,如果是这样,我能做些什么来强制它第一次走成功的路径?

第一次连接的漫长等待仅仅是因为初始化 Oracle 池管理器的成本吗?如果是这样,我想我无法修复它的那部分,但即使是这样,我仍然想知道是否有可能做任何事情来摆脱 SocketException。

当 SocketException 被命中时,.NET 端的堆栈跟踪如下所示:

System.dll!System.Net.Sockets.Socket.EndConnect(System.IAsyncResult asyncResult)
System.dll!System.Net.Sockets.TcpClient.EndConnect(System.IAsyncResult asyncResult)
Oracle.ManagedDataAccess.dll!OracleInternal.Network.TcpTransportAdapter.Connect(OracleInternal.Network.ConnectionOption conOption)
Oracle.ManagedDataAccess.dll!OracleInternal.Network.OracleCommunication.ConnectViaCO(OracleInternal.Network.ConnectionOption connOption, OracleInternal.Network.AddressResolution addrRes)
Oracle.ManagedDataAccess.dll!OracleInternal.Network.OracleCommunication.DoConnect(string tnsDescriptor)
Oracle.ManagedDataAccess.dll!OracleInternal.Network.OracleCommunication.Connect(string tnsDescriptor, bool externalAuth, string instanceName)
Oracle.ManagedDataAccess.dll!OracleInternal.ServiceObjects.OracleConnectionImpl.Connect(Oracle.ManagedDataAccess.Client.ConnectionString cs, bool bOpenEndUserSession, string instanceName)
Oracle.ManagedDataAccess.dll!OracleInternal.ConnectionPool.PoolManager<OracleInternal.ConnectionPool.OraclePoolManager,OracleInternal.ConnectionPool.OraclePool,OracleInternal.ServiceObjects.OracleConnectionImpl>.CreateNewPRThreadFunc(object state)
mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)
mscorlib.dll!System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
mscorlib.dll!System.Threading.ThreadPoolWorkQueue.Dispatch()

查看 Oracle .trc 文件,似乎没有什么异常。

4

2 回答 2

1

主要问题似乎与 listener.ora 和 tnsnames.ora 配置有关。

这是一个本地 12c 标准数据库服务器安装,并且 listener.ora 配置文件包含一个 IPC 协议条目,我在安装过程中肯定没有要求它包含它。一旦我运行网络配置助手重新配置监听器,这个条目就消失了。此外,TCP 协议的主机名从 localhost 更改为真实机器名。

至于 tnsnames.ora,网络配置助手将描述符中的主机名从 localhost 更新为真实机器名,并删除了 SERVER = DEDICATED 值。

我很确定我在 12c 数据库服务器的标准/典型安装期间的任何时候都没有指定 localhost,但响应文件确实包含条目“ORACLE_HOSTNAME=localhost”,所以要么我指定了这个,要么安装程序默认为这个值。

但就 SocketException 而言,罪魁祸首似乎是 listener.ora 配置文件中存在 IPC 协议条目。

我不再看到内部的第一次 SocketException 和 OracleConnection.Open 执行时间现在减少到不到半秒,即比原来的情况少了一秒。

编辑

我可以确认标准 12c 数据库的典型安装将

  • 默认将 ORACLE_HOSTNAME 设置为 localhost,这将在 listener.ora 和 tnsnames.ora 中使用。

  • 将 IPC 协议条目添加到侦听器描述符。

于 2014-05-27T08:58:52.853 回答
0
 Dim oradb As String = "Data Source=(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = orcl)));User Id=username;Password=password;"
 Dim conn As New OracleConnection(oradb)
 conn.Open()
于 2014-05-27T06:57:42.300 回答