我编写了一个Java程序,该程序连接到我服务器上的数据库,以查找记录、写入记录、更新和删除。由于某种原因,查找记录有效,但大多数时候,当我尝试保存或写入记录时,它会给出错误消息:
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
The last packet successfully received from the server was 9,787 milliseconds ago. The last packet sent successfully to the server was 8,183 milliseconds ago.
Caused by: java.io.EOFException: Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.
at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:2552)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3002)
... 46 more
谁能解释为什么会发生这种情况? 通常,当我让软件运行超过半分钟后,尝试添加记录时,这会给我错误消息。好像连接松了或者什么的。当我运行程序并快速写入新记录时,它起作用了
我也遇到了同样的问题。我引用了很多帖子和评论,但对我有用的是更改
my.cnf
文件的一些参数。希望它也能帮助你......
在 my.cnf [mysqld] 部分
设置以下参数interactive_timeout=180 # "No.of sec. a server waits for activity on interactive connection before closing it"
wait_timeout=180 # "No. of sec. a server waits for an activity on a connection before closing it"
max_connect_errors=9999 # "More than this number of interrupted connections from a host this host will be blocked from further connections"
skip-name-resolve # "Don't resolved host names. All host names are IP's"
有时此问题是由于系统 RAM 的大小引起的。可能是您通过 RAM 使用缓冲区插入数据。为了摆脱这个问题。
你可以通过下面的代码来理解这一点。
public static void main(string args[])
{
Connection con = null;
Statement stm = null;
int i;
float ratio;
ratio=1.0f;
try
{
Class.forName("com.mysql.jdbc.Driver");
// Connecting to the database
con = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/demo",
"ashish", "impetus");
File f = new File("filler"); // taking the random text data from the file
// filler.txt and inserting that string
// in filler field of the relations
RandomAccessFile r = new RandomAccessFile(f,"r");
Random randomGenerator = new Random();
String strLine=new String();
int r1,flag=0;
stm = con.createStatement();
con.setAutoCommit(false) ;
int k=0;
i=0;
long sum2=0;
while(k%50000==0)
{
final long start = currentTimeMillis();
final StringBuilder builder =
new StringBuilder("INSERT INTO accounts
(aid, bid,abalance,filler) VALUES ");
while(i!=naccounts*ratio*scale )
{
int j=i+1;
for(int l=0;l<40;l++)
{
strLine+=((char)r.read());
r.skipBytes(0);
}
r1=randomGenerator.nextInt(1500);
if(strLine.equals(""))
{
flag=1;
}
if(flag!=1)
{
strLine=strLine.replaceAll("\\s","");
strLine=strLine.replaceAll("\\t","");
}
flag=0;
if (i%50000!=0)
{
builder.append(",");
}
builder.append(format("(%s, %s, %s, '%s')", j,
i/naccounts+1, 0, strLine));
strLine="";
r.seek(r1);
i++;
if(i%50000==0||i>=naccounts*ratio*scale)
{
final String query = builder.toString();
final PreparedStatement statement1 = con.prepareStatement(query);
statement1.execute();
con.commit();
final long stop= currentTimeMillis();
sum2=sum2+(stop-start);
statement1.close();
}
if(i%50000==0||i>=naccounts*ratio*scale)
{
break;
}
}
k=k+50000;
if(k>naccounts*ratio*scale)
{
break;
}
}
System.out.println(i+" rows inserted accounts table ");
System.out.println("time taken = "+sum2+" milliseconds");
}
catch (SQLException e)
{
System.out.println("Connection Failed! Check output console");
e.printStackTrace();
return;
}
catch (Exception e)
{
e.printStackTrace();
}
}
您遵循/阅读本教程了吗:
您的例外情况有一部分对您有用。
我将引用一些有关您的特定例外情况的内容,请尝试一下:
如果收到 SQLException:连接被拒绝或连接超时 或 MySQL 特定的 CommunicationsException: Communications link 失败,则意味着数据库根本无法访问。这个可以 有以下一种或多种原因:
JDBC URL 中的 IP 地址或主机名错误。 JDBC URL 中的主机名是 本地 DNS 服务器无法识别。端口号缺失或错误 JDBC 网址。数据库服务器已关闭。数据库服务器不接受 TCP/IP 连接。数据库服务器已耗尽连接。东西在 Java 和 DB 之间的连接是阻塞的,例如防火墙或代理。
要解决其中一个问题,请遵循以下建议:
使用 ping 验证并测试它们。刷新 DNS 或在 JDBC 中使用 IP 地址 改为网址。根据MySQL DB的my.cnf进行验证。启动数据库。 验证 mysqld 是否在没有 --skip-networking 选项的情况下启动。 重新启动数据库并相应地修复您的代码以使其关闭 连接终于进来了。禁用防火墙和/或配置 防火墙/代理来允许/转发端口。
对于我来说,我使用 TiDb 作为数据库,tidb 服务器内存是 16GB,我升级到 32GB,问题暂时解决了。