声明结束后不允许任何操作
No operations allowed after statement closed.
我收到了Exception,并No operations allowed after statement closed.
签名No operations allowed after statement closed.
在我的Java代码中,我试图将值插入数据库。 错误签名说我的Statement对象被关闭了,我试图在我的代码中再次使用它,但我正在努力理解的是为什么会发生这种情况,因为我没有关闭代码中的任何连接。
这是Java代码。
public class DataBaseAccessUtils { private static String jdbcUrl = AppConfig.findMap("BXRequestTracker").get("jdbcUrl").toString(); private static Connection connection = null; private static Statement statement = null; public static void insertHostname(String hostname, String rid, String fleet, String locale) { locale.toUpperCase(); String sql = "UPDATE " + locale + "REQUESTTRACKER SET " + fleet + "='" + hostname + "' WHERE RID='" + rid + "'"; try { statement.execute(sql); } catch (SQLException e) { e.printStackTrace(); } } public static Statement connectToDatabase() { try { Class.forName("com.mysql.jdbc.Driver"); connection = DriverManager.getConnection(DataBaseAccessUtils.jdbcUrl); statement = connection.createStatement(); } catch (Exception e) { e.printStackTrace(); } return statement; }
此外,我观察到,当存在单个线程执行时,错误不会发生,当多个线程尝试同时更新数据库时,它会出现。
创建一个用于连接管理的Utility类,以便在整个应用程序中的单点管理它。
每次需要新连接时都不要加载DataSource
。
示例代码:
public class ConnectionUtil { private DataSource dataSource; private static ConnectionUtil instance = new ConnectionUtil(); private ConnectionUtil() { try { Context initContext = new InitialContext(); dataSource = (DataSource) initContext.lookup("JNDI_LOOKUP_NAME"); } catch (NamingException e) { e.printStackTrace(); } } public static ConnectionUtil getInstance() { return instance; } public Connection getConnection() throws SQLException { Connection connection = dataSource.getConnection(); return connection; } public void close(Connection connection) throws SQLException { if (connection != null && !connection.isClosed()) { connection.close(); } connection = null; } }
始终关闭连接并在try-catch-finally
处理它
Connection conn = null; PreparedStatement stmt = null; ResultSet rs = null; try { conn = ConnectionUtil.getInstance().getConnection(); ... } finally { if (rs != null) { rs.close(); } if (stmt != null) { stmt.close(); } if (conn != null) { ConnectionUtil.getInstance().close(conn); } }
statement
是静态的,因此它在实例(和线程)之间共享。 一个线程可能在另一个线程关闭之后尝试使用该对象。
在线程之间共享数据库连接和语句通常是一个坏主意,因为JDBC不要求连接是线程安全的。
可能是因为您正在为两个不同的方法使用相同的close(pst.close())
准备语句,并且您在一个方法中close(pst.close())
语句并仍尝试在另一个方法中使用相同的语句。
要解决此问题,请在您遇到此错误的代码块中获取新连接,然后使用statement。
如果您对两种不同的方法使用相同的语句,并且如果您不在任何方法中关闭语句,那么您可能会收到此错误:
参数索引超出范围(2>参数个数,即1)。
因为同样的陈述。 因此,尝试为代码块获取单独的连接和语句,然后关闭连接和语句。