informix jdbc 卡住了连接
Posted
技术标签:
【中文标题】informix jdbc 卡住了连接【英文标题】:informix jdbc stuck connecting 【发布时间】:2014-02-05 08:35:24 【问题描述】:我正在尝试使用标准方式通过 jdbc 连接到 Informix 数据库服务器:
connection = DriverManager.getConnection("jdbc:informix-sqli://"+ip+
/"+sid+":INFORMIXSERVER="+server+";user="+user+";password="+pass+"");
但它一直在尝试连接并且不会抛出错误消息(我想它会尝试连接,因为它没有显示任何内容)。我正在使用 IBM Informix 驱动程序 4.10.00.1534 和 Java 1.7。 到目前为止,我一直在使用这种方法连接到 Informix 服务器,实际上它只在一台服务器上失败。我可以使用 odbc 通过 Informix 客户端连接到此服务器,但使用 jdbc 时一直失败,没有错误消息。
有什么方法可以详细说明 jdbc 连接吗?关于它为什么失败的任何建议?
更新:sqlidebug 跟踪:
C->S (4)
SQ_VERSION
SQ_EOT
S->C (14)
SQ_VERSION
"7.31.TD6" [8]
SQ_EOT
C->S (66)
SQ_INFO
INFO_ENV
Name Length = 12
Value Length = 8
"DBTIME"="%d/%M/%Y"
"DBTEMP"="/tmp"
"SUBQCACHESZ"="10"
INFO_DONE
SQ_EOT
S->C (2)
SQ_EOT
C->S (16)
SQ_DBOPEN
"database" [8]
NOT EXCLUSIVE
SQ_EOT
S->C (28)
SQ_DONE
Warning..: 0x15
# rows...: 0
rowid....: 0
serial id: 0
SQ_COST
estimated #rows: 1
estimated I/O..: 1
SQ_EOT
C->S (78)
SQ_PREPARE
# values: 0
CMD.....: "select site from informix.systables where tabname = ' GL_COLLATE'" [65]
SQ_NDESCRIBE
SQ_WANTDONE
SQ_EOT
jdbctrace.log 说:
trying com.informix.jdbc.IfxDriver
SQLWarning: reason(Database selected) SQLState(01I04)
SQLWarning: reason(Float to decimal conversion has been used) SQLState(01I05)
SQLWarning: reason(Database has transactions) SQLState(01I01)
SQLWarning: reason(Database selected) SQLState(01I04)
SQLWarning: reason(Database has transactions) SQLState(01I01)
SQLWarning: reason(Database selected) SQLState(01I04)
【问题讨论】:
【参考方案1】:尝试运行连接 Informix 数据库的代码,同时显示完整的异常信息并创建跟踪文件。一个跟踪文件用于 JDBC,一个用于 Informix。将 URL 更改为数据库、用户名和密码,然后运行它。您可能会在屏幕或跟踪文件中看到问题:
import java.io.FileWriter;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
class informix_trace
public static void main(String[] args)
try
Class.forName("com.informix.jdbc.IfxDriver");
FileWriter fwTrace = new FileWriter("c:\\JDBCTrace.log");
PrintWriter pwTrace = new PrintWriter(fwTrace);
DriverManager.setLogWriter(pwTrace);
String debug_url = "SQLIDEBUG=C:\\sqlidebug.trace";
String url = "jdbc:informix-sqli://1.2.3.4:9088/test_db:informixserver=ol_testifx;DB_LOCALE=pl_PL.CP1250;CLIENT_LOCALE=pl_PL.CP1250;charSet=CP1250;" + debug_url
Connection connection = DriverManager.getConnection(url, "user", "passwd");
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery("SELECT FIRST 1 DBINFO('version','full') FROM systables;");
while (resultSet.next())
System.out.println(resultSet.getObject(1));
catch (Exception e)
e.printStackTrace();
// class informix_trace
Informix 跟踪文件将带有一些后缀(时间戳或类似信息),就我而言,它类似于sqlidebug.trace1391758523500.0
。它是二进制的,但您可以使用 sqliprt
实用程序对其进行分析。
我的数据库名称错误的会话示例:
c:\>sqliprt sqlidebug.trace1391758523500.0
SQLIDBG Version 1
...
S->C (12)
SQ_ERR
SQL error..........: -329
ISAM/RSAM error....: -111
Offset in statement: 0
Error message......: "" [0]
SQ_EOT
在JDBCTrace.log
我可以找到更多有趣的信息(我也在我的屏幕上看到):
SQLState(IX000) vendor code(-111)
java.sql.SQLException: ISAM error: no record found.
at com.informix.util.IfxErrMsg.getSQLException(IfxErrMsg.java:413)
at com.informix.jdbc.IfxSqli.E(IfxSqli.java:3412)
at com.informix.jdbc.IfxSqli.dispatchMsg(IfxSqli.java:2324)
....
at java.sql.DriverManager.getConnection(Unknown Source)
at informix_trace.main(informix_trace.java:20)
getConnection failed: java.sql.SQLException: No database found or wrong system privileges.
(我是从波兰语翻译过来的,所以可能有点不同)
【讨论】:
我已经尝试了您建议的调试语句,但它没有完成调试文件的打印,在某些时候它冻结并且没有继续打印。我已经用结果更新了答案。再次感谢 我收到异常“线程“main”中的异常 java.lang.NoClassDefFoundError:无法初始化类 net.snowflake.client.jdbc.SnowflakeDriver”。任何人都可以提出建议。【参考方案2】:我的建议是:
-
构建 ConnectString 并向我们展示其全部内容,这样我们将查看
ip
中是否只有 IP 地址或是否带有端口号
使用getConnection()
的3个参数版本而不是向ConnectString添加用户名和密码,就像:
getConnection("jdbc:informix-sqli://169.0.5.10:9088/test_db:informixserver=ol_test;DB_LOCALE=pl_PL.CP1250;CLIENT_LOCALE=pl_PL.CP1250;charSet=CP1250", username, password)
(当然设置你自己的语言环境而不是我的波兰语言环境)
要监视网络流量,请使用 Wireshark 等工具。开始捕获到 Informix 数据库的 ip 流量。就我而言,Wireshark 规则是:
ip.addr == 169.0.5.10
如果我设置了错误的 IP,Wireshark 会显示“Destination unreachable”。
您还可以使用 netstat 看到一些东西:
c:\>netstat -an | grep 9088
TCP 169.0.1.126:4295 169.0.5.10:9088 TIME_WAIT
那是我的应用程序停止工作的时候。
如果出现错误(错误的 IP 端口),我会看到:
c:\>netstat -an | grep 9089
TCP 169.0.1.126:4398 169.0.5.10:9089 SYN_SENT
【讨论】:
我已经尝试过您关于getConnection()
和netstat 的3 参数版本的建议(我无法在此处安装wireshark)。 3 参数版本没有改变任何东西,它一直尝试连接并且不返回错误代码(构建的 url 使用 ip:port 标准)并且收集的 netstat 信息仅表示与服务器建立了连接但似乎没有回应。非常感谢您的宝贵时间。【参考方案3】:
IBM says that: From version 3.00.JC1 of IBM® Informix® JDBC Driver onwards, debug drivers are no longer shipped.
Informix JDBC Driver now supports SQLIDEBUG. You no longer need to set values for TRACE, TRACEFILE or PROTOCOLTRACE, PROTOCOLTRACEFILE. You only need to set SQLIDEBUG.
然后页面继续概述了创建跟踪所需的步骤。复制:
将 CLASSPATH 设置为 Informix JDBC 驱动程序包。
c:\Infx\Java>设置 CLASSPATH=C:\infx\JDBC3.00JC3\lib\ifxjdbc.jar;C:\infx\JDBC3.00JC3\lib\ifxjdbcx.jar;.
编译simple.java
c:\Infx\Java>javac simple.java
确保 SQLIDEBUG 设置正确
c:\Infx\Java>grep SQLIDEBUG simple.java conn=DriverManager.getConnection("jdbc:informix-sqli://irk:1526/sysmaster:INFORMIXSERVER=irk940;USER=informix; 密码=ximrofni;SQLIDEBUG=C:\infx\java\trace");
注意:SQLIDEBUG 设置在连接字符串中。它指向哪里 跟踪文件将以某种格式找到,即 trace.xxxxxx
删除或移动所有其他跟踪文件
c:\Infx\Java>删除跟踪*
运行 java.simple
c:\Infx\Java>java 简单的 systables syscolumns ... ... 老头子
然后找到跟踪文件
c:\Infx\Java>dir trace* 驱动器 C 中的卷没有标签。体积 序列号为 B823-46D8
c:\Infx\Java 目录
04/04/2006 14:12 20,560 trace1144156355642.0 1 文件 20,560 字节 0 Dir(s) 4,067,995,648 字节空闲
c:\Infx\Java>
您将能够看到已经创建了一个跟踪文件 您将无法读取该文件。
将跟踪文件发送到您当地的技术支持办公室 分析。
当然,如果您不使用版本 3.00.JC1 的 Informix 驱动程序,请忽略以上内容和follow a different set of instructions;为了您的方便,再次复制:
要打开跟踪,请指定环境变量 TRACE, 数据库 URL 中的 TRACEFILE、PROTOCOLTRACE 和 PROTOCOLTRACEFILE 或 与 Informix 建立连接时的属性列表 数据库或数据库服务器。 TRACE 可以设置为以下之一 级别:
未启用跟踪。这是默认值。 跟踪方法的入口和出口点。 与级别 1 相同,此外还会跟踪一般错误消息。 与级别 2 相同,此外还跟踪数据变量。 TRACEFILE 指定客户端上操作系统文件的完整路径名 写入 TRACE 消息的计算机。
PROTOCOLTRACE 跟踪您的 Java 之间发送的 SQLI 协议消息 程序和 Informix 数据库服务器。
可设置为以下级别:
未启用协议跟踪。这是默认值。 跟踪消息 ID。 同级别 1,另外还跟踪消息包中的数据。 PROTOCOLTRACFILE 指定操作的完整路径名 PROTOCOLTRACE 消息发送到的客户端计算机上的系统文件 都写好了。
希望有帮助
【讨论】:
【参考方案4】:-
尝试不同的 jdbc 版本
检查NETTYPE配置参数并将其与当前informix会话数进行比较
当 jdbc 连接挂起时转储 java 线程状态(kill -3)
【讨论】:
【参考方案5】:import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import com.informix.*;
public class DBConnect
static String url="jdbc:informix-sqli://host_name:port/database_name:INFORMIXSERVER=server;user=username;password=password";
public static void main(String [] args)
try
Class.forName("com.informix.jdbc.IfxDriver");
catch (Exception e)
System.out.println("ERROR: failed to load Informix JDBC driver.");
e.printStackTrace();
return;
try
DriverManager.registerDriver((com.informix.jdbc.IfxDriver)Class.forName("com.informix.jdbc.IfxDriver").newInstance());
catch(Exception ex)
System.out.println("Driver is not Registered");
try
Connection conn = DriverManager.getConnection(url);
System.out.println("Connection Successful");
catch (SQLException e)
System.out.println("ERROR: failed to connect!");
System.out.println("ERROR: " + e.getMessage());
e.printStackTrace();
return;
欲了解更多信息,请阅读 [这本书] (http://www.cursor-distribution.de/aktuell.11.70.xC6/documentation/ids_jdbc_bookmap.pdf)
【讨论】:
【参考方案6】:我遇到的问题是 Informix 正在侦听端口 7360 上的本地 IPv6 地址,命令 netstat -a
显示这种格式:
TCP [feab::11ab:78ab:efab:8aab%17]:7360 myhostname:0 LISTENING
因此,我的 jdbc 连接总是失败,直到我发现我应该在 URL 中使用 IPv6 地址:
jdbc:informix-sqli://fe80::1125:78c0:ef17:8ab5%17:7360:user=informix;password=test;INFORMIXSERVER=ol_informix1210_2
您可以使用这个简单的脚本测试连接是否正常工作:
/***************************************************************************
*
* Title: SimpleConnection.java
*
* Description: Demo a connection to a server (no database specified)
*
* An example of running the program:
*
* java SimpleConnection
* 'jdbc:informix-sqli://myhost:1533:user=<username>;password=<password>'
*
* Expected result:
*
* >>>Simple Connection test.
* URL = "jdbc:informix-sqli://myhost:1533:user=<username>;password=<password>"
* >>>End of Simple Connection test.
*
***************************************************************************
*/
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class SimpleConnection
public static void main(String[] args)
if (args.length == 0)
System.out.println("FAILED: connection URL must be provided in order to run the demo!");
return;
String url = args[0];
String testName = "Simple Connection";
Connection conn = null;
System.out.println(">>>" + testName + " test.");
System.out.println("URL = \"" + url + "\"");
try
Class.forName("com.informix.jdbc.IfxDriver");
catch (Exception e)
System.out.println("FAILED: failed to load Informix JDBC driver.");
try
PrintWriter out = new PrintWriter(System.out, true);
DriverManager.setLogWriter(out);
conn = DriverManager.getConnection(url);
catch (SQLException e)
System.out.println("FAILED: failed to connect!");
try
conn.close();
catch (SQLException e)
System.out.println("FAILED: failed to close the connection!");
System.out.println(">>>End of " + testName + " test.");
【讨论】:
以上是关于informix jdbc 卡住了连接的主要内容,如果未能解决你的问题,请参考以下文章
我可以将锁定模式设置为在 Informix - JDBC - tomcat 连接池中等待吗?
为啥 Informix JDBC 驱动程序处理不相关的连接字符串?
尝试使用 JDBC 连接到 IBM 的 Informix docker 版本