【问题标题】:ActiveJdbc second connection to same databaseActiveJdbc 第二次连接到同一个数据库
【发布时间】:2018-09-07 10:19:17
【问题描述】:

我正在将 activejdbc 用于我必须为学校做的 Java ee 项目,我真的很喜欢它。但是,当我需要在一个 HttpServletRequest 中与同一个数据库建立多个连接时,我确实会遇到一个反复出现的问题。

场景如下: 我有一个自定义标签,它列出了每个请求都会调用的用户购物车的内容,因为我将它放在我的 header.jsp 中。在这个标签中,我向 activeJdbc 询问该用户购物车的内容。它看起来像这样:

Base.open("com.mysql.jdbc.Driver", "jdbc:mysql://localhost/wpr_webshop", "root", "root");
            Iterator<Record> rIter = shopCart.getAll(Record.class).iterator();


            if (rIter.hasNext()) {
                int shoppingCartTotal = 0;
                out.write("<div class='shoppingcartcontents'>Your cart contains:<br>");

                while (rIter.hasNext()) {
                    Record r = rIter.next();
                    Artist a = r.parent(Artist.class);

                    out.write(a.getString("artist_name") + " - " + r.getString("title") + "<br />");
                    shoppingCartTotal += r.getInteger("price");
                }
                Base.close();

然后,在一个 servlet 中呈现一个 jsp,该 jsp 包含使用上面的标签的 jsp,我用 activejdbc 做一些额外的事情,比如正常的记录选择;还在同一个数据库上使用Base.open(),这给了我一个

org.javalite.activejdbc.DBException: Cannot open a new connection because existing connection is still on current thread, name: default, connection instance: com.mysql.jdbc.JDBC4Connection@2c2552bd. This might indicate a logical error in your application.

异常。我知道这里的问题是什么,一旦我不再需要它,我已经非常彻底地关闭了基本连接,但我似乎无法阻止这个问题。

我想解决这个问题的方法是允许在每个请求上调用的自定义标记使用不同的连接,以免与基本连接发生冲突。不幸的是,我找不到任何有关如何在网络上打开与同一数据库的第二个连接的信息。

这甚至可能吗?还是我只是做错了?

【问题讨论】:

    标签: jsp servlets jakarta-ee activejdbc


    【解决方案1】:

    在使用 Java EE 时不建议使用 Base.open,因为已经内置了更好的机制,即 JDBC 连接池。请参阅 https://stackoverflow.com/a/16261491/8707412 了解如何配置它们。然后可以将这些包含在您的代码中

    @Resource(name="jdbc:app/myDS")
    DataSource ds;
    

    然后您可以从中获取连接

    Connection conn = ds.getConnection();
    

    【讨论】:

    【解决方案2】:

    通常,在标签甚至 servlet 中打开连接是一个糟糕的主意。一个完整的请求不应该打开许多到同一个数据库的连接,而是在线程上共享它。从您的代码中删除所有Base.open()/close() 调用并编写一个简单的ServletFilter,它将在请求之前打开一个连接并在之后关闭它。

    这是一个示例:ActiveJdbcFilter - 它使用 JNDI,但您可以使用此代码作为指导。

    有关管理连接的文档,请参阅:http://javalite.io/database_connection_management

    另一方面,您的代码两次调用rIter.hasNext() - 这是故意的吗?

    此外,这里有一个更好的循环实现:

    List<Record> records  = shopCart.getAll(Record.class).include(Artist.class);
    
    for(Record r: records){    
      Artist a = r.parent(Artist.class);
    }
    

    【讨论】:

    • 嗨,ipolevoy,一如既往,非常足智多谋。我将连接移至网络过滤器,这解决了我的所有问题。循环正在进行中,但感谢您指出。再说一次,我不得不说 ActiveJdbc 给我留下了深刻的印象。更不用说大力支持了。非常感谢,你让我作为菜鸟的生活变得更好了。最良好的祝愿,derelektrischemoench
    • @derelektrischemoench 你取得了很大的进步,祝你好运!你可能想支持我的回答:)
    猜你喜欢
    • 2023-03-10
    • 1970-01-01
    • 2014-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-13
    相关资源
    最近更新 更多