在开始写之前,先描述一下这次的数据库环境。数据库为oracle10g,2台机器进行的双击热备。(如果你的数据库不是双机热备,那么以下的解决思路可能不适用于你。)
昨天同事打电话,数据库连接不上了。。症状是,应用服务器能连接上数据库,但是,短信发送的系统连接不上数据库。遇到这问题就感觉很奇怪,应用和短信的系统都在同一台服务器上,应用能连接数据库,短信却不能连接数据库。于是乎登录服务器,查看短信系统的报错信息:
java.sql.SQLException: Io 异常: Connection refused(DESCRIPTION=(TMP=)(VSNNUM=169870336) (ERR=12514)(ERROR_STACK=(ERROR=(CODE=12514)(EMFI=4))))
ERR=12514,从上面的报错信息大致可以看出,oracle的监听进程无法解析当前连接描述中的服务名。但是,更让我感觉奇怪的是,应用系统和短信系统的连接url完全相同,应用能连接数据库,短信系统却不可以。以下是jdbc连接URL:
url=jdbc:oracle:thin:@(DESCRIPTION = (FAILOVER=ON)(ADDRESS=(PROTOCOL=TCP)(HOST=ip1)(PORT=1521)) (ADDRESS=(PROTOCOL=TCP)(HOST=ip3)(PORT=1521))(CONNECT_DATA =(SERVICE_NAME = db)(FAILOVER_MODE=(TYPE=SELECT)(METHOD=BASIC)(RETRIES=5)(DELAY=3)))) (数据库使用的双机热备,所以URL看上去有点怪。)
经过一番折腾加折磨和始终无解的情况下,采取让短信系统只连一个库。。于是,将短信系统的url修改为:
url=jdbc:oracle:thin:@ip3:1521:db
然后,开启系统。更加悲剧的事情发生了,又报错了。。。
java.sql.SQLException: Io 异常: Connection refused(DESCRIPTION=(TMP=)(VSNNUM=169870336)(ERR=12505)(ERROR_STACK=(ERROR=(CODE=12505)(EMFI=4))))
分析上面的报错信息,好像oracle服务器的监听器不能识别当前的SID。刚开始觉着这错误真稀奇,我用pl/sql和sqlplus都能连接上,在程序里用jdbc方式却无法连接上。通过网上搜索以及查看资料后,才恍然大悟:
1.使用sqlplus或pl/sql等工具连接oracle服务器时,只需要给出service_name就能连接上了。但是,如果使用jdbc连接则必须指定数据库的sid(可能与service_name不同) (我的问题就在这里,通过执行select instance_name from v$instance 获得的instance_name为db2。于是将上面的url修改为jdbc:oracle:thin:@ip3:1521:db2之后连接正常。)
2.客户端的tnsnames.ora中的网络服务名并不是SID,而是一个连接别名或者代号,oracle客户端或者其他连接工具在连接服务器是使用这个代号来解析其中的service_name.
最后,让我百思不得其解的是,为什么2个系统的连接URL完全相同,然而,短信系统却无法连接上数据库。忘高人指点。。谢谢。。。