我在TOmcat 6中使用连接池,我已经在context.xml文件中配置了这种方式
<Resource name="jdbc/myoracle" auth="Container"
type="javax.sql.DataSource" driverClassName="oracle.jdbc.OracleDriver"
url="jdbc:oracle:thin:@127.0.0.1:1521:ORCLE"
username="scott" password="tiger" maxActive="20" maxIdle="10"
maxWait="-1"/>
这是我的Factory类,用于获取使用DataSource的连接
public class ConnPoolFactory {
private static DataSource dataSource;
private static Connection connection;
private ConnPoolFactory() {
}
public static synchronized Connection getConnection() throws SQLException {
try {
if (connection == null) {
Context initContext = new InitialContext();
Context envContext = (Context) initContext
.lookup("java:/comp/env");
dataSource = (DataSource) envContext.lookup("jdbc/myoracle");
connection = dataSource.getConnection();
} else {
return connection;
}
} catch (NamingException e) {
e.printStackTrace();
}
return connection;
}
}
从我的servlet里面最后阻止,我这样关闭它
try {
connection = ConnPoolFactory.getConnection();
finally
{
if(conn!=null)
con.close();
}
从我的用户界面,我可以提供不同的命令(按下按钮),如插入,更新,删除,选择 - 。
我面临的问题是,应用程序只运行一个命令,例如,如果我单击“插入按钮”,它会正确插入记录,之后,如果我再次给出任何命令,则会出现异常在服务器控制台上说连接已关闭。
如果我在servlet中删除了最后的块代码,那么应用程序可以运行任意数量的命令
有人可以让我知道那个finnaly块的错误吗?
答案 0 :(得分:1)
Connection
中的ConnPoolFactory
变量应该是方法本地的,而不是静态的。您应该为null测试的变量不是connection
而是dataSource
。获得该值的非null值后,返回dataSource.getConnection()
。然后,呼叫者应该在完成连接后关闭该连接。
答案 1 :(得分:0)
您的工厂不知道连接已关闭,并继续将其移出。我假设这是你设计它的想法。
您应该让servlet在使用后转回连接,或者工厂每次都创建一个新连接。
编辑:尝试更明确:
每个请求都会调用一次servlet代码。这就是servlet所做的。在我看来,你在任何请求后关闭连接。精细。但是,您的连接工厂使用静态来存储它创建的连接。因此,在第二次调用时,它将分发一个已经关闭的连接(实际上,它是一个具有单个连接而不是工厂的连接池)。
顺便说一句,如果你不关闭你的连接,你可能会遇到另一个更糟糕的错误:如果两个请求同时发生,你将在servlet线程之间共享一个连接,这可能会或可能不会,这取决于你执行哪些数据库操作。 / p>