带有 JDBC 的 Java SQLException - SQLITE_MISUSE
Posted
技术标签:
【中文标题】带有 JDBC 的 Java SQLException - SQLITE_MISUSE【英文标题】:Java SQLException with JDBC - SQLITE_MISUSE 【发布时间】:2016-03-14 19:52:25 【问题描述】:我在我的 Java 应用程序中使用 SQlite。如果我运行我的程序,它会在某个时候出错。
有时这是一个简单的异常,有时 JVM 出现致命错误。
java.sql.SQLException: [SQLITE_MISUSE] 库使用不正确(内存不足)
Java 运行时环境检测到致命错误:
在 pc=0x000000006d587ab0, pid=7036, tid=6364 处的 EXCEPTION_ACCESS_VIOLATION (0xc0000005)
JRE 版本:Java(TM) SE 运行时环境 (8.0_73-b02) (build 1.8.0_73-b02) Java VM:Java HotSpot(TM) 64 位服务器 VM(25.73-b02 混合模式 windows-amd64 压缩 oops) 有问题的框架: C [sqlite-3.8.11.2-6df82281-eaf0-4204-a962-ce1e48ddd89f-sqlitejdbc.dll+0x7ab0]
无法写入核心转储。默认情况下,在 Windows 的客户端版本上不启用小型转储
包含更多信息的错误报告文件保存为: C:\Users\UltraMouse\workspace\co.windall.twitter\hs_err_pid7036.log
如果您想提交错误报告,请访问: http://bugreport.java.com/bugreport/crash.jsp 崩溃发生在 Java 虚拟机之外的本地代码中。 请参阅有问题的框架以了解报告错误的位置。
导致这种情况的代码行是
ResultSet rs = stmt.executeQuery("SELECT * FROM User WHERE id=" + id.toString() + ";");
这是不一致的,它每次都发生在不同的点(此代码处于循环中)但它总是发生。
这是我的完整源文件: http://pastebin.com/RKKVdNZ8 http://pastebin.com/fVaa93Rk
我每次都干净地运行它(我删除了数据库文件)。它目前在 file1 的第 102 行失败。
我不知道该怎么办:(
是的,这些 twitter 密钥现在可以使用,但仅限于读取访问权限,我将它们留在那里,以便您也可以在需要时试用该应用程序。
【问题讨论】:
因为解决您的问题的尝试似乎没有奏效,我建议您进行异常处理。不要只捕获异常,而是分别知道它的子类。这应该可以帮助您本地化错误代码。有了它,您可以自己解决或发布另一个问题。 【参考方案1】:很难看出到底出了什么问题,但您绝对应该在每次操作后关闭您的语句和ResultSet
s。
这很可能导致您看到的内存泄漏:
Statement stmt = connection.createStatement();
应该在每个新操作之前调用
stmt.close();
应该在每次操作后调用。所以总而言之,你的主循环应该是这样的:
for (Long id : ids)
Statement stmt;
ResultSet rs;
try
st = connection.createStatement();
rs = stmt.executeQuery("...");
if (rs.next())
Long ft = rs.getLong("followedThem");
rs.close();
st.close();
st = connection.createStatement();
String sql = "...";
if (ft != null && ft == -1)
sql = x;
else
sql = y;
st.executeUpdate(sql);
st.close();
catch (SQLException e)
【讨论】:
我确实是这样开始的,那段代码是在我搞砸了一点之后。循环中的语句没有区别。 我现在在同一个地方测试了它的错误:java.sql.SQLException: statement is not execution 现在有什么异常? @leumas95 您仍在使用您的语句对象来获取两个不同的结果集。我在回答中描述了这个问题。尝试对每个 ResultSet 使用新语句。 @epoch java.sql.SQLException: 语句未执行【参考方案2】:根据statement documentation
每个 Statement 对象只能同时打开一个 ResultSet 对象 时间
因此,您的语句的重用应该是问题,因为它隐式关闭了您的其他 ResultSet
Statement 接口中的所有执行方法都会隐式关闭一个 语句的当前 ResultSet 对象(如果存在打开的对象)。
但在某些情况下,循环可能需要再次关闭已经关闭的 ResultSet,因此会导致异常。
更新:
-
我会将两个语句的两个异常处理分开
我会使用两个语句对象
在我的代码中,我总是在尝试关闭 ResultSet 或 Statements 之前检查它们是否为 != null。
for (Long id : ids)
Statement st, st2;
ResultSet rs;
Long ft = 0;
try
st = connection.createStatement();
rs = st.executeQuery("SELECT * FROM User WHERE id=" + id.toString() + ";");
if (rs.next())
ft = rs.getLong("followedThem");
if (rs != null)
rs.close();
if (st != null)
st.close();
catch (SQLException e)
System.err.println(e.getClass().getName() + ": " + e.getMessage());
e.printStackTrace();
System.err.println(id);
System.exit(0);
if (ft != 0)
try
st2 = connection.createStatement();
String sql = "";
if (ft != null && ft == -1)
sql="UPDATE User SET followedThem=" + String.valueOf(Instant.now().getEpochSecond()) + " WHERE id=" + id.toString() + ";";
else
sql=String.format("INSERT INTO User (id,followedMe,followedThem,unfollowedMe,unfollowedThem,status) " +
"VALUES (%d, %d, %d, %d, %d, %d);", id, -1, Instant.now().getEpochSecond(), -1, -1, 0);
st2.executeUpdate(sql);
if (st2 != null)
st2.close();
catch (SQLException e)
System.err.println(e.getClass().getName() + ": " + e.getMessage());
e.printStackTrace();
System.err.println(id);
System.exit(0);
【讨论】:
以上是关于带有 JDBC 的 Java SQLException - SQLITE_MISUSE的主要内容,如果未能解决你的问题,请参考以下文章
带有 JDBC 的 Java SQLException - SQLITE_MISUSE
带有 maven 的 mysql 连接器:java.lang.NoClassDefFoundError: com/mysql/jdbc/Driver