查看来自this等高信誉用户的答案,似乎通过在每个连接请求上查询JNDI命名服务来获取新的DataSource对象是合适的。例如。使用以下代码(为了更简洁,改编自链接的答案):
public class ConnectionManager{
public static Connection getConnection() throws NamingException {
Context initContext = new InitialContext();
Context envContext = (Context)initContext.lookup("java:/comp/env");
DataSource dataSource = (DataSource)envContext.lookup("jdbc/test");
return dataSource.getConnection();
}
}
这是真的,建议/惯用的方式吗?在我自己的一些“ConnectionManager”实用类中,我曾经将对DataSource对象的引用保持为实例变量。除非JBoss管理员从管理控制台禁用并启用连接池,然后我的代码出现如下错误,否则没有任何错误:
java.sql.SQLException: javax.resource.ResourceException: IJ000451: The connection manager is shutdown
那么,在JDBC中保留DataSource对象的实例是一种反模式吗?
答案 0 :(得分:1)
DataSource对象可以被高速缓存并且是线程安全的,尽管JNDI应该足够优化,使得每个请求从JNDI中获取DS可以忽略不计(相同的实例将从JNDI返回)。
例如,如果您在Java EE环境中工作,那么它的规范标准就是能够在类级别注入数据源,例如:
public class MyServlet extends HttpServlet {
@Resource
DataSource ds;
public void processRequest() {
try(Connection con = ds.getConnection()) {
// ...
}
}
}
此外,跨多个线程共享DataSource对象是完全安全的。另一方面,跨多个线程共享Connection
对象是一个很大的错误,因为这些对于每个规范都不是线程安全的。