从连接池获取数据库连接
我正在重构其他代码。我注意到的一件事是系统如何从连接池获取连接的方式。
样本是这样的。每次调用服务方法时,系统都会在 JNDI 上进行数据源的上下文查找。
public class CheckinServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
//Obtain Connection
InitialContext initialContext = new InitialContext();
javax.sql.DataSource ds = (javax.sql.DataSource) initialContext
.lookup("jdbc/mysqldb");
java.sql.Connection conn = ds.getConnection();
//business logic
//redirect
} finally {
conn.close();
}
}
}
我确实认为每次这样做都会对性能造成影响。我正在考虑另一种方法来解决这些问题,即如何从连接池中检索连接。
我正在考虑使用 servlet 的 init()
方法,但我认为这不是最佳选择。
I am refactoring others code. The one thing I notice is that of the manner on how the system is getting a connection from the connection pool.
Sample is like this. On every call of the service method, the system is making a context lookup on the JNDI for the datasource.
public class CheckinServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
//Obtain Connection
InitialContext initialContext = new InitialContext();
javax.sql.DataSource ds = (javax.sql.DataSource) initialContext
.lookup("jdbc/mysqldb");
java.sql.Connection conn = ds.getConnection();
//business logic
//redirect
} finally {
conn.close();
}
}
}
I do think that there is a performance hit on doing this every time. I am thinking of another way around these on how to retrieve a connection from a connection pool.
I am thinking about using the servlet's init()
method but I think that is not optimal.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
在
ServletContextListener
而不是许多 servlet 的init()
中的每次。contextInitialized()
方法在 webapp 启动期间仅执行一次。在
web.xml
中配置如下:您可以在 servlet 中按以下方式获取它(
init()
或doXXX()
方法,您可以选择):不过,我会进一步重构它,JDBC 代码最好放置在它自己的类中,而不是放在 servlet 中。查找 DAO 模式。
Do it once in a
ServletContextListener
instead of everytime ininit()
of many servlets. ThecontextInitialized()
method is executed only once during webapp's startup.Configure it as follows in
web.xml
:You can obtain it in your servlet as follows (
init()
ordoXXX()
method, you choose):I'd however refactor it a step further, JDBC code should preferably be placed in its own classes, not in servlets. Lookup the DAO pattern.
我过去使用的方法是创建一个保存数据源的单例类,
例如
这意味着您拥有对数据源的共享引用,从而消除了 jndi 查找开销。
The method I have used in the past is to create a singleton class that holds the datasource
E.g.
This means that you have a shared reference to your datasource, taking away the jndi lookup overhead.
我刚刚对此做了一些测试,发现 jndi 查找时间并不那么繁重。这里大约 1 秒内进行 50.000 次查找。
所以在很多情况下,我根本看不出缓存数据源的原因。
缓存的问题是,如果您更改与数据源定义相关的任何内容,您可能会得到陈旧的数据源,迫使您重新启动应用程序。
I just did some testing with this, and found that jndi lookup time is not that heavy. 50.000 lookups in about 1 sec here.
So in many cases, I don't see a reason for caching the DataSource at all.
Problem with caching is that you might end up with a stale DataSource, forcing you to restart your app if you change anything related to the datasource definition.
除此之外,还有一种名为 Service Locator 的设计模式,它基本上是一个包含一个名为“service”的注册表的单例,该注册表保存您的 JNDI 对象。
基本上,如果在注册表中找不到该对象,则会从 JNDI 池中获取该服务并在注册表中注册。下一次调用将简单地从注册表中提取对象。
希望这有帮助。
Adding to what's said, there's a design pattern called Service Locator, which is a basically a singleton containing a registry called "service" that holds your JNDI objects.
Basically, if the object isn't found in the registry, the service is taken from the JNDI pool and registered in the registry. The next call will simply pull the object from registry.
Hope this helps.