验证 Oracle 数据库连接的一些棘手的快速方法
我的 WCF 服务需要检查连接现在是否可用以及我们是否可以使用它。我们有很多远程数据库。它们的连接有时很奇怪,不能用于查询数据或其他东西。 因此,例如,这是使用的常规连接字符串:
User Id=user;Password=P@ssw0rd;Data Source=NVDB1;Connection Timeout=30
这是服务方法,用于让
public List<string> GetAliveDBs(string city)
{
if (String.IsNullOrEmpty(city))
return null;
List<string> cityDbs = (from l in alldbs where !String.IsNullOrEmpty(l.Value.city) && l.Value.city.ToUpper() == city.ToUpper() select l.Value.connString).ToList();
// There is no such city databases
if (cityDbs.Count == 0)
return null;
ReaderWriterLockSlim locker = new ReaderWriterLockSlim();
Parallel.ForEach(cityDbs, p =>
{
if (!IsConnectionActive(p.connString))
{
locker.EnterWriteLock();
try
{
cityDbs.RemoveAt(cityDbs.IndexOf(p));
}
finally
{
locker.ExitWriteLock();
}
}
});
return cityDbs;
}
static public bool IsConnectionAlive(string connectionString)
{
using (OracleConnection c = new OracleConnection(connectionString))
{
try
{
c.Open();
if ((c.State == ConnectionState.Open) && (c.Ping()))
return true;
else
return false;
}
catch (Exception exc)
{
return false;
}
}
}
我使用 devart 组件与 Oracle DB 进行通信。 希望得到你们的帮助,伙计们!提前致谢!
My WCF service need to check is connection available now and can we work with it. We have many remote dbs. Their connection are weird sometimes and can't be used to query data or smth else.
So, for example this is regular connection string used:
User Id=user;Password=P@ssw0rd;Data Source=NVDB1;Connection Timeout=30
Here is service method, used for getting
public List<string> GetAliveDBs(string city)
{
if (String.IsNullOrEmpty(city))
return null;
List<string> cityDbs = (from l in alldbs where !String.IsNullOrEmpty(l.Value.city) && l.Value.city.ToUpper() == city.ToUpper() select l.Value.connString).ToList();
// There is no such city databases
if (cityDbs.Count == 0)
return null;
ReaderWriterLockSlim locker = new ReaderWriterLockSlim();
Parallel.ForEach(cityDbs, p =>
{
if (!IsConnectionActive(p.connString))
{
locker.EnterWriteLock();
try
{
cityDbs.RemoveAt(cityDbs.IndexOf(p));
}
finally
{
locker.ExitWriteLock();
}
}
});
return cityDbs;
}
static public bool IsConnectionAlive(string connectionString)
{
using (OracleConnection c = new OracleConnection(connectionString))
{
try
{
c.Open();
if ((c.State == ConnectionState.Open) && (c.Ping()))
return true;
else
return false;
}
catch (Exception exc)
{
return false;
}
}
}
I use devart components to communicate with Oracle DB.
Hope for your help, guys! Thanks in advance!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
尝试只执行一个成本非常低的操作,无论您连接到什么模式,该操作都应该有效,例如
SELECT 1
(该语句适用于 MS SQL 和 MySQL...也应该适用于 Oracle,但我无法确认)。
如果得到预期的结果(在本例中为一行,一列,包含“1”),则连接有效。
至少有一个连接池管理器使用此策略定期验证连接。
更新:
这是您的方法的 SQL Server 版本。您可能只需将“Sql”替换为“Oracle”即可。
Try just executing a very low cost operation that should work no matter what schema you are connected to, e.g.
SELECT 1
(that statement works on MS SQL and MySQL... should work on Oracle too but I can't confirm that).
If you get the result you expect (in this case one row, with one column, containing a "1") then the connection is valid.
At least one connection pool manager uses this strategy to validate connections periodically.
UPDATE:
Here's a SQL Server version of your method. You can probably just replace "Sql" with "Oracle".
如果目标是简单地确定服务器是否位于该 IP 地址或主机名处,那么我建议使用 Ping(没有 3 路握手,并且开销比 UDP 消息少)。您可以使用 System.Net.NetworkInformation.Ping 类(请参阅其 文档 为例)。
如果您想证明确实有东西在监听公共 Oracle 端口,我建议使用
System.Net.Sockets.TcpClient
或System.Net.Sockets.Socket
< /a> 类(他们的文档也提供了示例)来提供这一点。(到目前为止)最简单的方法是使用 Oracle API for C# 打开一个连接。有一个非常好的教程,其中包含代码 这里。它不仅仅涵盖连接,但您应该能够从其余部分中剥离连接部分以满足您的需求。
If the goal is to simply determine if a server lives at the IP Address or host name then I'd recommend Ping (no 3 way handshake and has less overhead than a UDP message). You can use the
System.Net.NetworkInformation.Ping
class (see its documentation for an example) for this.If you're looking to prove that there is actually something listening on the common Oracle port, I would suggest using either the
System.Net.Sockets.TcpClient
orSystem.Net.Sockets.Socket
class (their documentation also provides examples) to provide this.The simplest way to do this (by far) is to just open a connection using the Oracle API for C#. There is a very good tutorial that includes code here. It covers more than just the connection but you should be able to strip out the connection portion from the rest to fit your needs.
Oracle 拥有专门用于帮助维护高可用性的产品和软件,允许您通过连接字符串上名为
HA Events=true
的设置从连接池中删除死连接。您的 Oracle DBA 需要确定您的安装是否支持它。Oracle has products and software specifically for helping maintain high availability that can allow you to have dead connections removed from you connection pool through a setting called
HA Events=true
on the connection string. Your Oracle DBA will need to determine if your installation supports it.