我使用activejdbc作为Java ee项目我必须为学校做,我真的很喜欢它。但是,每当我在一个HttpServletRequest中需要多个连接到同一个数据库时,我就会遇到一个反复出现的问题。
方案如下: 我有一个自定义标签,列出了每个请求都会调用的用户购物车的内容,因为我将它放在我的header.jsp中。在此标记中,我向activeJdbc询问此用户的shoppingcart的内容。它看起来像这样:
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,它使用了上面的标记,我使用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.
异常。我知道这里的问题是什么,只要我不再需要它,我就已经非常彻底地关闭了基本连接,但我似乎无法阻止这个问题。
我想解决这个问题的方法是允许每个请求调用的自定义标记使用不同的连接,以免与基本连接冲突。遗憾的是,我无法找到有关如何在网络上打开与同一数据库的第二个连接的任何信息。
这甚至可能吗?或者我只是以错误的方式做这件事?
答案 0 :(得分:1)
使用Java EE时不建议使用Base.open
,因为已经内置了一种更好的机制,即JDBC连接池。请参阅https://stackoverflow.com/a/16261491/8707412以了解如何配置它们。然后可以使用
@Resource(name="jdbc:app/myDS")
DataSource ds;
然后,您可以使用
从中获取连接Connection conn = ds.getConnection();
答案 1 :(得分:0)
通常,在标记甚至servlet中打开连接是一个糟糕的主意。整个请求不应该打开与同一数据库的多个连接,而是在线程上共享它。从代码中删除所有truncate
调用并编写一个简单的ServletFilter,它将在请求之前打开一个连接并在之后关闭它。
以下是一个示例:ActiveJdbcFilter - 它使用JNDI,但您可以使用此代码作为指导。
有关管理连接的文档,请参阅:http://javalite.io/database_connection_management。
另一方面,您的代码调用了Base.open()/close()
两次 - 这是故意的吗?
此外,这是一个更好的循环实现:
rIter.hasNext()