Java 语句关闭后不允许进行任何操作
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23323653/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
No operations allowed after statement closed
提问by user2890683
I am getting the Exception with the signature No operations allowed after statement closed.
inside my Java code where I am trying to insert values into the database. The error signature says that my Statement object gets closed and I am trying to use it again in my code , but what I am struggling to understand is why is this happening as I am not closing any connections anywhere in my code.
我在No operations allowed after statement closed.
尝试将值插入数据库的 Java 代码中收到带有签名的异常。错误签名表示我的 Statement 对象已关闭,我正在尝试在我的代码中再次使用它,但我很难理解为什么会发生这种情况,因为我没有关闭代码中任何地方的任何连接。
Here is the Java code.
这是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;
}
Also I have observed that the error does not come when there is a single threaded execution , it comes up when multiple threads are trying to update the database simultaneously.
此外,我还观察到错误不会在单线程执行时出现,而是在多个线程尝试同时更新数据库时出现。
回答by keyser
statement
is static, so it's shared among instances (and threads). One thread is probably trying to use that object after another one has closed it.
statement
是静态的,因此它在实例(和线程)之间共享。一个线程可能在另一个线程关闭它之后尝试使用该对象。
It is generally a bad idea to share database connections and statements between threads since JDBC does not require connections to be thread-safe.
在线程之间共享数据库连接和语句通常是一个坏主意,因为 JDBC 不要求连接是线程安全的。
回答by Braj
Create a Utility class for connection management to manage it at single point in whole application.
创建一个用于连接管理的实用程序类,以在整个应用程序中进行单点管理。
Don't load the DataSource
every time you need a new connection.
不要在DataSource
每次需要新连接时加载。
Sample code:
示例代码:
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;
}
}
Always close the connection and handle it in try-catch-finally
始终关闭连接并处理它 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);
}
}
回答by faizan ahmad
It may be because of you are using the same prepared statement for two different
methods and you close(pst.close())
the statement in one method and still try to use same statement in another method.
这可能是因为您对两种不同的方法使用相同的准备好的语句,并且您close(pst.close())
在一种方法中使用该语句,并且仍然尝试在另一种方法中使用相同的语句。
To solve this, get a new connection in a code block you are facing this error and then use statement.
要解决此问题,请在遇到此错误的代码块中创建一个新连接,然后使用语句。
One thing more if you are using same statement for two different methods and if you do not close statement in any method then you may get this error:
如果您对两种不同的方法使用相同的语句,并且没有在任何方法中关闭语句,则还有一件事,那么您可能会收到此错误:
Parameter index out of range (2 > number of parameters, which is 1).
参数索引超出范围(2 > 参数数量,即 1)。
because of same statement . So try to get separate connection and statement for block of code and then close the connection and statement.
因为同样的声明。因此,尝试为代码块获取单独的连接和语句,然后关闭连接和语句。