我真的很困惑这个问题,所以我很高兴有人可以帮助我!
当我在一分钟之后登录时系统在我再次尝试登录时退出时出现此错误:com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException:连接关闭后不允许任何操作。
如何阻止此连接关闭。什么是这个
的最佳连接池注意:我仍然是第一个做CRUD的学习者! 数据库工具:
private static Connection connet;
public static Connection getConnection() {
if( connet != null )
return connet;
InputStream inputStream = DButil.class.getClassLoader().getResourceAsStream( "/db.properties" );
Properties properties = new Properties();
try {
properties.load( inputStream );
String url = properties.getProperty("url");
String driver = properties.getProperty("driver");
String userName = properties.getProperty("user");
String password = properties.getProperty("password");
Class.forName(driver);
connet = DriverManager.getConnection(url,userName,password);
} catch (IOException | ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
return connet;
}
// connection commit
public static void commit() {
try {
connet.commit();
} catch (Exception e) {
e.printStackTrace();
}
}
// rollback data
public static void rollback() {
if (connet != null) {
try {
connet.rollback();
} catch (SQLException ex) {
ex.printStackTrace();
}
}
}
// close Connection
public static void closeConnection( Connection toBeClosed ) {
if( toBeClosed == null )
return;
try {
toBeClosed.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
数据库属性:
url = jdbc:mysql://localhost:3306/dbname?autoReconnect=true
driver = com.mysql.jdbc.Driver
user = usernanem
password = password
DaoImplemetation:
private Connection connet;
public UsersDaoImplementation()
{
connet=DButil.getConnection();
}
@Override
public void addUser(Users user) {
try {
String query = "INSERT INTO Users (First_Name, Last_Name, Address, Phone_Number, UserName, Password, idRole, Date_of_Birth) VALUES (?,?,?,?,?,?,?,?)";
PreparedStatement preparedStatement = connet.prepareStatement( query );
preparedStatement.setString(1, user.getFirst_Name());
preparedStatement.setString(2, user.getLast_Name());
preparedStatement.setString(3,user.getAddress());
preparedStatement.setInt(4, user.getPhone_Number());
preparedStatement.setString(5, user.getUserName());
preparedStatement.setString(6, user.getPassword());
preparedStatement.setInt(7, user.getIdRole());
//preparedStatement.setDate(8, (Date) user.getDate_of_Birth());
//preparedStatement.setDate(8, (java.sql.Date) user.getDate_of_Birth());
preparedStatement.setDate(8, new java.sql.Date (user.getDate_of_Birth().getTime()));
preparedStatement.executeUpdate();
preparedStatement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public void deleteUser(int idUsers) {
try {
String query ="DELETE FROM Users WHERE idUsers = ?";
PreparedStatement preparedStatement = connet.prepareStatement( query );
preparedStatement.setInt(1, idUsers);
preparedStatement.executeUpdate();
preparedStatement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public void updateUser(Users user) {
try {
String query = "UPDATE Users SET First_Name=?, Last_Name=?, Address=?, Phone_Number=?, UserName=?, Password=?, idRole=?, Date_of_Birth=?";
PreparedStatement preparedStatement = connet.prepareStatement( query );
preparedStatement.setString(1, user.getFirst_Name());
preparedStatement.setString(2, user.getLast_Name());
preparedStatement.setString(3,user.getAddress());
preparedStatement.setInt(4, user.getPhone_Number());
preparedStatement.setString(5, user.getUserName());
preparedStatement.setString(6, user.getPassword());
preparedStatement.setInt(7, user.getIdRole());
preparedStatement.setDate(8, new java.sql.Date (user.getDate_of_Birth().getTime()));
preparedStatement.executeUpdate();
preparedStatement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public List<Users> getAllUsers() {
List<Users> users = new ArrayList<Users>();
try {
Statement statement = connet.createStatement();
ResultSet resultSet = statement.executeQuery( "SELECT * FROM Users" );
while (resultSet.next())
{
Users user = new Users();
user.setIdUsers(resultSet.getInt("idUsers"));
user.setFirst_Name(resultSet.getString("First_Name"));
user.setLast_Name(resultSet.getString("Last_Name"));
user.setAddress(resultSet.getString("Address"));
user.setPhone_Number(resultSet.getInt("Phone_Number"));
user.setUserName(resultSet.getString("UserName"));
user.setPassword(resultSet.getString("Password"));
user.setIdRole(resultSet.getInt("idRole"));
user.setDate_of_Birth(resultSet.getDate("Date_of_Birth"));
users.add(user);
}
resultSet.close();
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
return users;
}
@Override
public Users getUserbyId(int idUsers) {
Users user = new Users();
try {
String query = "SELECT * FROM Users WHERE idUsers=?";
PreparedStatement preparedStatement = connet.prepareStatement( query );
preparedStatement.setInt(1, idUsers);
ResultSet resultSet = preparedStatement.executeQuery();
while( resultSet.next() ) {
user.setIdUsers(resultSet.getInt("idUsers"));
user.setFirst_Name(resultSet.getString("First_Name"));
user.setLast_Name(resultSet.getString("Last_Name"));
user.setAddress(resultSet.getString("Address"));
user.setPhone_Number(resultSet.getInt("Phone_Number"));
user.setUserName(resultSet.getString("UserName"));
user.setPassword(resultSet.getString("Password"));
user.setIdRole(resultSet.getInt("idRole"));
user.setDate_of_Birth(resultSet.getDate("Date_of_Birth"));
}
resultSet.close();
preparedStatement.close();
}
catch (SQLException e) {
e.printStackTrace();
}
return user;
}
@Override
public boolean validate(String UserName, String Password) {
boolean status = false;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
String query = "SELECT * FROM Users WHERE UserName=? and Password=?";
preparedStatement = connet.prepareStatement( query );
preparedStatement.setString(1, UserName);
preparedStatement.setString(2, Password);
resultSet = preparedStatement.executeQuery();
status=resultSet.next();
} catch (SQLException e) {
e.printStackTrace();
}finally {
if (connet != null) {
try {
connet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (preparedStatement != null) {
try {
preparedStatement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
return status;
}
错误:
com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed.
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:377)
at com.mysql.jdbc.Util.getInstance(Util.java:360)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:935)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:924)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:870)
at com.mysql.jdbc.ConnectionImpl.throwConnectionClosedException(ConnectionImpl.java:1232)
at com.mysql.jdbc.ConnectionImpl.checkClosed(ConnectionImpl.java:1225)
at com.mysql.jdbc.ConnectionImpl.prepareStatement(ConnectionImpl.java:4104)
at com.mysql.jdbc.ConnectionImpl.prepareStatement(ConnectionImpl.java:4073)
at org.jupiterM.dao.UsersDaoImplementation.validate(UsersDaoImplementation.java:162)
at org.jupiterM.controller.LoginJ.doPost(LoginJ.java:63)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:528)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1099)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:670)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1520)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1476)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
答案 0 :(得分:2)
您有一个finally
块,其内容如下:
} finally {
if (connet != null) {
try {
connet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
...
}
由于connet
是一个字段,因此关闭的连接将保留在实例上;但它不会设置为null
。
这样做的结果是关闭的连接将返回给您,因为您检查的是它不是null
。
您可以通过更改获取新连接的代码来解决此问题:
if( connet != null && !connet.isClosed() )
return connet;
您应该做的另一件事是在connet
关闭时将null
设置为{{1}}。
答案 1 :(得分:2)
您有一个静态属性是您的连接。该对象将返回到dao中的方法。当你关闭他的连接时,你也在关闭静态连接。 (因为它们共享相同的参考)。您应该在每个方法上创建连接对象,或者查找用于控制连接的框架。连接池很难用纯jdbc方式实现。
答案 2 :(得分:2)
连接关闭后不允许任何操作。我怎么能阻止这个 连接关闭异常?
选项(1): 最后使用空检查关闭连接
您可以通过在null
块中添加finally
检查和关闭连接来阻止此操作,如下所示:
Connection conn = null;
try {
//your code
} catch(SQLException exe) {
//Log exceptions
} finally {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
我已经在你的代码中注意到,有时你正在关闭try里面的连接,这是不推荐的,因为如果try块在中间抛出SQLException
,conn.close()
将不会被执行,这是一个非常大的问题。因此,请确保您始终只在最后一个块中关闭连接,否则会产生资源泄漏(很快就会用完连接)。
选项(2): 您可以尝试使用资源(推荐,因为您无需担心关闭连接)
try(Connection conn = DButil.getConnection()) {
//your code
} catch(SQLException exe) {
//Log exceptions
}
在这里,在选项(2)中,您可以注意到此处没有finally
阻止,conn object
会自动closed
,您可以查看here有关try with resources.
如何处理代码的连接池?
手动处理连接(就像你做的那样)并不是最佳做法(因为它们的时间成本很高),所以你可以尝试使用Apache DBCP实现连接池,你可以参考{ {3}}了解更多信息。
答案 3 :(得分:0)
修复此错误是有争议的 - 因为您的方法的整个想法是错误的 - 在不同的线程之间共享单个连接(并且每个请求可能来自不同的线程)是明确禁止的。即使您使用其他建议之一并摆脱这一错误,您也会遇到更多错误 - 更糟糕的错误。一旦你添加任何类型的交易,你将永远无法使它工作。
如果您使用Java EE或Java EE Web Profile兼容服务器,它具有内置的连接池,以及配置它的工具,为每个请求创建新连接,安全地将连接返回到池并执行事务(甚至是两阶段提交)。有关如何配置它的确切细节是依赖于服务器的,通常有一个专有的配置文件或一些管理员gui。