半年前写的JDBC连接,昨晚发现突然出现常见的“恶心”的Socket连接错误,鼓捣了一个晚上,终于搞定,最终问题还是定位在SQLServer没有打上SP3补丁上。这是个老问题,但定位的过程有些值得写出来的地方,于是写了出来,也许还有兄弟也在迷惑中,希望能够给出一点点启示。
连接测试程序很简单,如下:
<%@ page pageEncoding="GB2312" import="java.sql.*"%>
<%
String DBDriver = "com.microsoft.jdbc.sqlserver.SQLServerDriver";
String DBUrl = "jdbc:microsoft:sqlserver://127.0.0.1:1433;DatabaseName=j2eestudy";
String DBUser = "j2eestudy";
String DBPass = "j2eestudy"; Connection conn = null;
try{
Class.forName(DBDriver);
conn = DriverManager.getConnection(DBUrl,DBUser,DBPass);
out.println("Connection is established!");
}
catch(Exception e){
e.printStackTrace(new java.io.PrintWriter(out));
}
%>
JDBC Driver也是采用了以前已经OK的项目的驱动(SP3),并且部署到了lib目录下,SQLServer DBMS采用混合认证模式,然而运行时却打印了熟悉的错误信息:
java.sql.SQLException: [Microsoft][SQLServer 2000 Driver for JDBC]Error establishing socket.
at com.microsoft.jdbc.base.BaseExceptions.createException(Unknown Source)
at com.microsoft.jdbc.base.BaseExceptions.getException(Unknown Source)
......
......
1)首先怀疑“j2eestudy”这个用户无法访问“j2eestudy”数据库,或没有分配足够的权限,但通过查询分析器登录、运行,没有问题,利用企业管理器查看用户权限及角色,也没有发现问题;
2)通过打印出来的错误栈信息知道,socket没有建立正确的连接,而socket是依靠IP和端口的,难道是1433端口有问题?在Shell下执行netstat -na命令,发现Listening的端口居然没有1433!
netstat -na
Active Connections
Proto Local Address Foreign Address State
TCP 0.0.0.0:135 0.0.0.0:0 LISTENING
TCP 0.0.0.0:443 0.0.0.0:0 LISTENING
TCP 0.0.0.0:445 0.0.0.0:0 LISTENING
TCP 0.0.0.0:1025 0.0.0.0:0 LISTENING
TCP 0.0.0.0:2393 0.0.0.0:0 LISTENING
TCP 0.0.0.0:2394 0.0.0.0:0 LISTENING
TCP 0.0.0.0:2725 0.0.0.0:0 LISTENING
TCP 0.0.0.0:8000 0.0.0.0:0 LISTENING
TCP 0.0.0.0:8009 0.0.0.0:0 LISTENING
TCP 0.0.0.0:8080 0.0.0.0:0 LISTENING
TCP 127.0.0.1:1026 0.0.0.0:0 LISTENING
TCP 127.0.0.1:8005 0.0.0.0:0 LISTENING
TCP 192.168.1.200:139 0.0.0.0:0 LISTENING
UDP 0.0.0.0:445 *:*
UDP 0.0.0.0:500 *:*
UDP 0.0.0.0:1032 *:*
UDP 0.0.0.0:1060 *:*
UDP 0.0.0.0:3456 *:*
UDP 0.0.0.0:4500 *:*
UDP 127.0.0.1:123 *:*
UDP 127.0.0.1:1031 *:*
UDP 127.0.0.1:1045 *:*
UDP 127.0.0.1:1312 *:*
UDP 127.0.0.1:1900 *:*
UDP 192.168.1.200:123 *:*
UDP 192.168.1.200:137 *:*
UDP 192.168.1.200:138 *:*
UDP 192.168.1.200:1900 *:*
没有道理啊,服务管理器明明运行的很正常,端口怎么会有问题呢?怀疑到可能是因为没有打上SP3a补丁的缘故。
3)下载补丁打上,重启服务管理器,运行netstat -na命令,发现1433端口已处在监听状态下。再次运行程序,提示数成功建立连接。
问题比较简单的解决掉了,之前也查过相关信息,但并没有开始就怀疑到SQLServer的SP3a补丁上,因为以前我是没有给SQLServer打过补丁的,项目并没有问题,一个容易忽视的变化是:我的OS从Win2K升级到了WinXP,其实正是因为这个原因,SQLServer2000在WinXP及以上的版本里,1433端口的监听是有问题的,因此必须为SQLServer打上SP3a补丁,Win2K环境下其实并不需要。
需要注意的是,所谓SP3补丁,即包括SP3的JDBC Driver,还包括SQLServer的SP3a补丁。后者并非必须,网上应该有很多兄弟有类似的问题,但很多文章并没有指出OS的版本问题。
问题解决很容易,直接打上补丁就好了,不过得到一个小小的教训,随着数据库的升级、JDK的升级甚至OS的升级,从前能够正常运行的程序,也许现在会有一定的问题,最好能够关注相关厂商的在版本上的修改是否对现有实现产生影响,及时作出跟进修改。
据说SQLServer2005很厉害。