java - 如何修复 com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException : No operations allowed after connection closed. 异常?

标签 java mysql jdbc transactions

这是我保存记录的查询。


public void saveTotal(JTextField txtGtotal, JTextField txtPTotal) {
    try {
        ResultSet rs = JDBC.getData("select MAX(or_id) as or_id from `order`");
        if (rs.first()) {
            if (rs.getInt("or_id") > 0) {
                try {
                    String date1 = new Validation().today();
                    boolean b1 = JDBC.putData("insert into transaction(tr_date, amount, tr_type) values ('" + date1 + "' , '" + txtGtotal.getText() + "' , 'order')");
                    if (b1) {
                        try {
                            ResultSet rs1 = JDBC.getData("select MAX(tr_id) as tr_id from transaction");
                            if (rs1.first()) {
                                try {
                                    boolean b2 = JDBC.putData("insert into transaction(tr_date, amount, tr_type) values ('" + date1 + "' , '" + txtPTotal.getText() + "' , 'profit')");
                                    if (b2) {
                                        try {
                                            ResultSet rs2 = JDBC.getData("select MAX(tr_id) as tr_id from transaction");
                                            if (rs2.first()) {

                                                try {
                                                    boolean b3 = JDBC.putData("insert into o_de(or_id, tr_id, oday, gtotal) values ('" + rs.getInt("or_id") + "' , '" + rs1.getInt("tr_id") + "','" + date1 + "','" + txtGtotal.getText() + "' )");
                                                    if (b3) {
                                                        try {
                                                            boolean b4 = JDBC.putData("insert into order_profit(or_id, tr_id, ptotal) values ('" + rs.getInt("or_id") + "' , '" + rs1.getInt("tr_id") + "','" + txtPTotal.getText() + "' )");
                                                            if (b4) {
                                                                JDBC.commit();
                                                                JOptionPane.showMessageDialog(null, "Order Saved Sucessfully..");
                                                                JDBC.putClose();
                                                                JDBC.conClose();

                                                            }
                                                        } catch (Exception e) {
                                                            JDBC.rollback();
                                                            e.printStackTrace();
                                                        } finally {
                                                            JDBC.putClear();
                                                            JDBC.conClear();
                                                        }
                                                    }
                                                } catch (Exception e) {
                                                    e.printStackTrace();
                                                }

                                            }

                                        } catch (Exception e) {
                                            e.printStackTrace();
                                        }
                                    }
                                } catch (Exception e) {
                                    JDBC.rollback();
                                    e.printStackTrace();
                                }
                            }
                        } catch (Exception e) {
                            JDBC.rollback();
                            e.printStackTrace();
                        }

                    }
                } catch (Exception e) {
                    JDBC.rollback();
                    e.printStackTrace();
                }
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }

}


这是我的 JDBC 类。

     package Modle;

  import java.sql.Connection;
  import java.sql.DriverManager;
  import java.sql.PreparedStatement;
  import java.sql.ResultSet;
  import java.sql.SQLException;
  import java.sql.Statement;
  import java.util.logging.Level;
  import java.util.logging.Logger;

  public class JDBC {

static Connection con = null;
static boolean b;
static PreparedStatement state;

public static void setCon() {
    try {
        Class.forName("com.mysql.jdbc.Driver");
        con = DriverManager.getConnection("jdbc:mysql://localhost:3306/lottery", "root", "123");
    } catch (Exception ex) {
        ex.printStackTrace();
    }
}

public static Connection getCon() throws Exception {
    if (con == null) {
        setCon();
    }
    return con;
}

public static boolean putData(String sql) {
    try {
        getCon().setAutoCommit(false);
        state = getCon().prepareStatement(sql);
        state.executeUpdate();
        b = true;
    } catch (Exception e) {
        e.printStackTrace();
        b = false;
    }
    return b;
}

// connection commit
public static void commit() {
    try {
        con.commit();
    } catch (Exception e) {
        e.printStackTrace();
    }

}

  // rollback data
  public static void rollback() {
    if (con != null) {
        try {
            con.rollback();
        } catch (SQLException ex) {
            Logger.getLogger(JDBC.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

// close statement
public static void putClose() {
    try {
        state.close();
    } catch (SQLException ex) {
        Logger.getLogger(JDBC.class.getName()).log(Level.SEVERE, null, ex);
    }
}
 // close connection

  public static void conClose() {
    try {
        con.setAutoCommit(true);
        con.close();
    } catch (SQLException ex) {
        Logger.getLogger(JDBC.class.getName()).log(Level.SEVERE, null, ex);
    }
}

// clear prepared statement
public static void putClear() {
    try {
        if (state != null && !state.isClosed()) {
            state.close();
        }
    } catch (SQLException ex) {
        Logger.getLogger(JDBC.class.getName()).log(Level.SEVERE, null, ex);
    }
}

// clear the connection
public static void conClear() {
    try {
        if (con != null && !con.isClosed()) {
            con.setAutoCommit(true);
            con.close();
        }
    } catch (SQLException ex) {
        Logger.getLogger(JDBC.class.getName()).log(Level.SEVERE, null, ex);
    }
}

public static ResultSet getData(String sql) throws Exception {
    Statement state = getCon().createStatement();
    ResultSet rs = state.executeQuery(sql);
    return rs;
 }
 }


这是我第一次尝试在 mysql 中进行事务处理。我知道这不是借口。但我对这种连接处理只有一个粗略的了解。如果我的代码不完善,请给我一个演示答案。


如何解决此连接关闭后不允许操作异常?谢谢。


也添加了堆栈跟踪。我认为还有另外两个地方也发现了同样的错误。他们在运行此查询之前就来了。

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:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
at com.mysql.jdbc.Util.getInstance(Util.java:386)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1013)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:987)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:982)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:927)
at com.mysql.jdbc.ConnectionImpl.throwConnectionClosedException(ConnectionImpl.java:1206)
at com.mysql.jdbc.ConnectionImpl.checkClosed(ConnectionImpl.java:1198)
at com.mysql.jdbc.ConnectionImpl.createStatement(ConnectionImpl.java:2484)
at com.mysql.jdbc.ConnectionImpl.createStatement(ConnectionImpl.java:2466)
at Modle.JDBC.getData(JDBC.java:115)
at Controler.NewOrderCon2.saveTotal(NewOrderCon2.java:196)
at lottery.NewOrder.jButton6ActionPerformed(NewOrder.java:2350)
at lottery.NewOrder.access$1200(NewOrder.java:28)
at lottery.NewOrder$13.actionPerformed(NewOrder.java:537)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2341)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
at java.awt.Component.processMouseEvent(Component.java:6505)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
at java.awt.Component.processEvent(Component.java:6270)
at java.awt.Container.processEvent(Container.java:2229)
at java.awt.Component.dispatchEventImpl(Component.java:4861)
at java.awt.Container.dispatchEventImpl(Container.java:2287)
at java.awt.Component.dispatchEvent(Component.java:4687)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4492)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4422)
at java.awt.Container.dispatchEventImpl(Container.java:2273)
at java.awt.Window.dispatchEventImpl(Window.java:2719)
at java.awt.Component.dispatchEvent(Component.java:4687)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:729)
at java.awt.EventQueue.access$200(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:688)
at java.awt.EventQueue$3.run(EventQueue.java:686)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
at java.awt.EventQueue$4.run(EventQueue.java:702)
at java.awt.EventQueue$4.run(EventQueue.java:700)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:699)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)

最佳答案

您是否知道您实际上是从 GUI 中访问后端?您正在将参数从文本字段直接传递到数据库。这是主要搞砸的来源。至少验证您的输入,或 Little Bobby Tables将提前终止您的工作契约(Contract)。

关于您的错误:抱歉,此代码需要进行重大重构。单从行数来看,这段代码就做的太多了。第一条黄金法则:保持你的方法简短。第二条黄金法则:让它们更短。

您自己不了解正在发生的事情这一事实对您来说是一个大红灯,表明您需要重新考虑您的设计。

  • 使使用 JDBC.putData() 编写内容的方法独立。
  • 对 JDBC.getData() 执行相同的操作。
  • 看到正在出现的模式。

我猜这是对 JDBC 中 connection.close() 的过早调用。通过将您的操作分解为更原子的操作,您可以更好地推理您的代码,从而理解手头的错误。

很抱歉没有提供解决方案,但从长远来看,坚持一些代码原则会更好。学习他们!越快越好,因为我需要更多业力: 阅读 Robert C. Martin 的“Clean-Code”。 http://www.amazon.de/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882

然后您将走上启蒙之路,从而使用 DAOFactory(提示)和 DAO 设计模式(也提示)并成为编码器大神。恭喜!

好吧,这里有一个关于重构外观的小指南。未完成且未经测试,我想我搞砸了 SQL 插入序列(不知道在哪里使用了哪个 transactionId)。但我希望你会有所了解。 祝你有美好的一天,欢迎来到牙买加!

package mysqlfix;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JTextField;

public class JDBC {

    static Connection con = null;
    static boolean b;
    static PreparedStatement state;

    public static void setCon() {
        try {
            Class.forName("com.mysql.jdbc.Driver");
            con = DriverManager.getConnection("jdbc:mysql://localhost:3306/lottery", "root", "123");
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public static Connection getCon() throws Exception {
        if (con == null) {
            setCon();
        }
        return con;
    }

    public static boolean putData(String sql) {
        try {
            getCon().setAutoCommit(false);
            state = getCon().prepareStatement(sql);
            state.executeUpdate();
            getCon().commit();
            b = true;
        } catch (Exception e) {
            e.printStackTrace();
            b = false;
        }
        return b;
    }

// connection commit
    public static void commit() {
        try {
            con.commit();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    // rollback data
    public static void rollback() {
        if (con != null) {
            try {
                con.rollback();
            } catch (SQLException ex) {
                Logger.getLogger(JDBC.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

// close statement
    public static void putClose() {
        try {
            state.close();
        } catch (SQLException ex) {
            Logger.getLogger(JDBC.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    // close connection

    public static void conClose() {
        try {
            con.setAutoCommit(true);
            con.close();
        } catch (SQLException ex) {
            Logger.getLogger(JDBC.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

// clear prepared statement
    public static void putClear() {
        try {
            if (state != null && !state.isClosed()) {
                state.close();
            }
        } catch (SQLException ex) {
            Logger.getLogger(JDBC.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

// clear the connection
    public static void conClear() {
        try {
            if (con != null && !con.isClosed()) {
                con.setAutoCommit(true);
                con.close();
            }
        } catch (SQLException ex) {
            Logger.getLogger(JDBC.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public static ResultSet getData(String sql) throws Exception {
        Statement state = getCon().createStatement();
        ResultSet rs = state.executeQuery(sql);
        return rs;
    }

    public void saveTotal(JTextField txtGtotal, JTextField txtPTotal) {
        SuperDAO superDAO = new SuperDAO();

        if (superDAO.getMaxIdFromOrder() > 0) {
            Date date1;
            date1 = new Date();
            String txtGTotalFromTextField = txtGtotal.getText();
            String txtPTotalFromTextField = txtPTotal.getText();
            boolean b1 = false;
                    //regarding the transaction id...
            //this changes whilst updating the table transaction.

            int transactionId = -1;
            if (txtGTotalFromTextField.matches("[a-zA-Z]")) {
                transactionId = superDAO.insertOrderIntoTransaction(date1, txtGTotalFromTextField);
                //b1 = JDBC.putData("insert into transaction(tr_date, amount, tr_type) values ('" + date1 + "' , '" + txtGTotalFromTextField + "' , 'order')");
            }
            if (transactionId > 0) {
                try {
                } catch (Exception ex) {
                    Logger.getLogger(JDBC.class.getName()).log(Level.SEVERE, null, ex);
                }
                if (txtPTotalFromTextField.matches("[a-zA-Z]")) {
                    transactionId = superDAO.insertProfitIntoTransaction(date1, txtGTotalFromTextField);
                }
                JDBC.putData("insert into o_de(or_id, tr_id, oday, gtotal) values ('" + superDAO.getMaxIdFromOrder() + "' , '" + transactionId + "','" + date1 + "','" + txtGtotal.getText() + "' )");
                JDBC.putData("insert into order_profit(or_id, tr_id, ptotal) values ('" + superDAO.getMaxIdFromOrder() + "' , '" + transactionId + "','" + txtPTotal.getText() + "' )");

                                                        //JDBC.commit();
                //JOptionPane.showMessageDialog(null, "Order Saved Sucessfully..");
                JDBC.putClose();
                JDBC.conClose();

            }

        }

    }

}



package mysqlfix;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author edm
 */
public class SuperDAO {

    Connection conn;

    public SuperDAO() {
        try {
            this.conn = JDBC.getCon();
        } catch (Exception ex) {
            Logger.getLogger(SuperDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public int getMaxIdFromOrder() {

        try {
            ResultSet rs = JDBC.getData("select MAX(or_id) as or_id from `order`");
            if (rs.first()) {

                return rs.getInt("or_id");
            }
        } catch (SQLException ex) {
            Logger.getLogger(SuperDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (Exception ex) {
            Logger.getLogger(SuperDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
        return -1;
    }

    public int getMaxIdFromTransaction() {
        ResultSet rs;
        try {
            rs = JDBC.getData("select MAX(tr_id) as tr_id from transaction");
            if (rs.first()) {
            return rs.getInt("tr_id");
        }
        } catch (Exception ex) {
            Logger.getLogger(SuperDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
        return -1;
    }


    public int insertOrderIntoTransaction(Date date, String text) {
        JDBC.putData("insert into transaction(tr_date, amount, tr_type) values ('" + date + "' , '" + text + "' , 'order')");
        return getMaxIdFromTransaction();
    }

     public int insertProfitIntoTransaction(Date date, String text) {
        JDBC.putData("insert into transaction(tr_date, amount, tr_type) values ('" + date + "' , '" + text + "' , 'profit')"); 

        return getMaxIdFromTransaction();
    }



}

当然,旅程并不止于此。我没有完成 JDBC saveTotal()。我才开始,剩下的由你来做。

请注意,我没有针对数据库测试此代码(某些 sql ddl 文件丢失)。另外,我没有使用回滚机制。此外,saveTotal() 存在于 JDBC 中,它不属于那里。在您的 GUI 中使用 saveTotal(如果需要)并让所有数据库访问流经 SuperDAO。这不是最好的设计,但它不是太抽象,您可以轻松地看到关注点分离如何使您的代码更具可读性和可维护性。

关于java - 如何修复 com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException : No operations allowed after connection closed. 异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27908953/

相关文章:

mysql - 如何在 mysql SELECT 的 WHERE 中设置超过 2 个过滤器

mysql - 如何使用单个sql语句将输入与表的两列进行比较?

java - JDBC ODBC ..(线程 "AWT-EventQueue-0"java.lang.NullPointerException 中出现异常)

java - JDBC 结果集聚合函数

java - 使用 Glide 加载 SVG 时图像变得模糊

java - 在 JPanel 中运行 Java 程序

java - Jackson:如何反序列化我自己的类的实例字段

java - 如何为 docbook 创建 JAXB 绑定(bind)

卡麦利奥中的 MYSQL

java - 使用 jdbc 将枚举值保存并读取到数据库?