程序抛出 [SQLITE_BUSY] 数据库文件已锁定(数据库已锁定)错误,但我已经关闭了所有内容

问题描述 投票:0回答:1

我实现了一个使用单例模式创建数据库连接的程序,如下所示:

public abstract class DAO {

private static Connection con;

static {
    try {
        Class.forName("org.sqlite.JDBC");
    } catch (ClassNotFoundException ex) {
        // Handle exception appropriately (e.g., log it)
        ex.printStackTrace();
    }
}

protected DAO() {}

public static Connection getConnection() throws SQLException {
    // Double-checked locking for better performance
    if (con == null) {
        synchronized (DAO.class) {
            if (con == null) {
                con = DriverManager.getConnection("jdbc:sqlite:/Users/riley/Desktop/project.db");
            }
        }
    }
    return con;
}

// DAO can handle its own connection closing, no need for a separate method
public static void closeConnection() {
    if (con != null) {
        try {
            con.close();
            System.out.println("Database connection closed.");
        } catch (SQLException ex) {
            // Handle exception appropriately (e.g., log it)
            ex.printStackTrace();
        } finally {
            con = null; // Ensure con is set to null after closing
        }
    }
}

}

我有几个类为我的数据库中的各种实体扩展了这个抽象类,即。用户、汽车和订单历史记录。

仅当我对此 servlet 中调用的数据库执行更新操作时,才会调用该问题:

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
    //String clear = request.getParameter("clear");
    
    CarDAO cardao = new CarDAO();
        
    HttpSession session = request.getSession();
    
    Cart cart = (Cart)session.getAttribute("cart");
    if(cart == null)
        cart = new Cart();
    
    String buy = request.getParameter("buy");
    
    if(buy == null) {
        int id = Integer.parseInt(request.getParameter("id"));
        
        boolean contains = false;
        int index = 0;
        for(int i = 0; i < cart.getOrders().size(); i++) {
            if(cart.getOrders().get(i).getId() == id) {
                contains = true;
                index = i;
            }
        }
        
        if(contains) {
            cart.getOrders().get(index).setQtyOrdered(cart.getOrders().get(index).getQtyOrdered() + 1);
        } else {
            
            Car car = cardao.getCar(id);
            car.setQtyOrdered(1);
            cart.addItem(car);
            
        }
        
        session.setAttribute("cart", cart);
        request.getRequestDispatcher("catalog.jsp").forward(request, response);
    } else {
        for(Car car : cart.getOrders()) {
            cardao.updateQuantity(car.getId(), car.getQtyInStock() - car.getQtyOrdered());
        }
        
        cart.clearCart();
        request.getRequestDispatcher("checkoutView.html").include(request, response);
    }
}

处理 updateQuantity 方法的方法位于 CarDAO 类中,即:

    public void updateQuantity(int id, int quantity) {
    //System.out.println("No error...");
    String sql = "update cars set quantity="+quantity+" where id="+id;
    
    try {
        Connection con = super.getConnection();
        
        Statement statement = con.createStatement();
        
        statement.executeUpdate(sql);
        statement.close();
    } catch(SQLException e) {
        System.out.println(e);
    } finally {
        super.closeConnection();
    }
}

正如我在标题中所述,我尝试了各种方法,例如每次调用 getConnection 方法时关闭连接,我也将 close() 行添加到 ResultSet 和语句中。似乎没有什么可以解除锁定。请帮忙。

java jdbc dao
1个回答
0
投票

程序有几个问题。

  1. 你的单例类应该是最终的,而不是抽象的。它应该只作为实用程序类工作。作为其他 DAO 类的基类,这不是一个好的选择。
  2. 不要在每次通话后关闭连接。获取数据库连接是一个成本高昂的过程。当您的应用程序关闭时关闭数据库连接。为此使用钩子。
  3. 不确定您是否检查过像这样的其他答案SQLite异常:SQLite Busy
  4. 您在关闭任何数据库连接或任何其他资源时是否遇到任何异常?如果是,这可能就是问题所在。
© www.soinside.com 2019 - 2024. All rights reserved.