【发布时间】:2018-11-13 14:59:43
【问题描述】:
我必须使用自定义 jdbc 连接池库来连接到 mysql db。
问题是我的插入没有保留在 db 中...为了缩小问题范围,我提取了插入 db 的库代码部分并有一些奇怪的发现:
MysqlConnectionPoolDataSource ds1 = new MysqlConnectionPoolDataSource();
ds1.setUser("usr");
ds1.setPassword("pwd");
ds1.setServerName("server");
ds1.setPort(port);
ds1.setDatabaseName("dbname");
ds1.setUseSSL(false);
ds1.setAllowPublicKeyRetrieval(true);
Connection conn = ds1.getPooledConnection("usr", "pwd").getConnection();
logger.info("connection " + conn.toString());
PreparedStatement ps = null;
ResultSet rs = null;
try {
String query = "INSERT INTO ...";
ps = conn.prepareStatement(query);
int timeout = 10;
ps.setQueryTimeout(timeout);
logger.info("timeout: " + timeout);
logger.info("Starting query execution for query: " + query);
long qeStart = System.currentTimeMillis();
ps.setString(1, "...");
ps.executeUpdate();
long qeEnd = System.currentTimeMillis();
logger.info("Query execution completed in " + (qeEnd - qeStart) + "msec.");
} catch (Exception e) {
logger.error("ERROR OCCURED", e);
System.err.println("ERROR OCCURED");
e.printStackTrace();
} finally {
closeResultSet(rs);
closeStatement(ps);
closeConnection(conn);
}
当我连接到版本为 8.0.11-commercial 的远程 mysql 数据库时,上面的代码不起作用。不工作是指没有错误,插入只是丢失了......
当我对我的本地 mysql 数据库执行相同的代码时,版本:8.0.11 托管在 Windows 机器上,它正在工作......
如果我从
更改连接获取代码Connection conn = ds1.getPooledConnection("usr", "pwd").getConnection();
到:
Connection conn = ds1.getConnection();
它也开始对远程 mysql db 使用版本:8.0.11-commercial...
底层连接的自动提交模式已经是真的...
我尝试实现一个自定义 log4j 记录器,希望能看到一些踪迹,但这也无济于事:
ds1.setLogger("com.ibtech.mysqlproblem.Log4jLogger");
我的自定义连接池库使用池连接,所以我需要让上面的代码工作。在客户端中,我使用的是 mysql-connector-java-8.0.11.jar。
非常感谢任何帮助...
【问题讨论】:
-
为什么不切换到经过良好测试的连接池而不是维护自己的自定义实现?只要代码使用理智的抽象,例如
java.sql.DataSource应该对应用程序逻辑没有影响。 -
嗨,卡罗尔,由于部署、管理决策等原因,这是不可能的。但是上面的代码演示了没有任何连接池的问题......我在一个隔离的主类中执行它并看到同样的错误.您对实际问题有什么建议吗?
-
我能给你的唯一建议是切换到HikariCP。编写一个correct and handles weird behaviours 的池很棘手。
-
如上代码所示,我目前的问题与池无关............
-
你似乎认为
MysqlConnectionPoolDataSource是一个连接池,它是NOT。ConnectionPoolDataSource旨在作为连接池中保存的连接的工厂。换句话说,它被一个连接池使用。您不应该直接在代码中使用它。无论如何,您是否尝试过使用conn.commit()?