我正试图围绕从JSF Web应用程序建立与数据库的JDBC连接的正确方法。解决此问题的常用方法是在应用程序服务器中创建数据源,并通过其代码中的JNDI名称连接到该数据源。实质上,所有用户都将在整个会话期间通过池共享相同的数据库用户帐户。
不幸的是,我正在努力的新项目的要求阻止我这样做。连接到应用程序的每个用户都必须使用唯一凭据登录RDBMS。我有一个关于如何实现与此相关的代码的草图,但我并不是100%清楚整体架构。 应用程序服务器(Tomcat,Glassfish,WebLogic)是否具有支持此功能的功能?
现在,我似乎能够实现这一目标的唯一方法是让每个用户会话直接创建一个返回数据库的JDBC连接。虽然我相信这会奏效,但感觉不对。
我错过了什么吗?
答案 0 :(得分:1)
你遗漏了一些东西 - 我非常假设:合理的系统设计。 ;)使用数据库凭据管理用户的整个想法仅适用于管理数据库的一个用例。对于其他一切,它会带来更多的问题,而不是它的好处...所以让shitstorm开始...;)
BOT:存在两难问题。您基本上必须为每个用户创建一个连接池,因为否则每次数据源在连接超时中运行时都必须创建与数据库的连接。三次握手加身份验证并不是一件便宜的事情 - 延迟会扼杀你的表现。虽然可以相应地配置一些驱动程序,但这通常是一个坏主意,并且大多数驱动程序由于所谓的“关注点分离”而不善于自己管理连接。另一方面,每个连接“池”只需要大约5个连接,因为同一个用户不太可能并行执行许多操作。
注意:我所知道的唯一一个管理连接和池的驱动程序是MongoDB的驱动程序。
现在出现问题:您无法将连接池附加到会话。不是走了几英里,我怀疑这是完全可能的。
解决此问题的一个想法是在用户登录并使用JNDI动态注册时为其创建连接池。问题是这不是很可扩展(假设您有几百个用户)。因此,您必须确保在会话终止时(通过注销或超时)删除池。另外,必须维护代码。
另一个想法是使用Apache Shiro并编写一个自定义Realm,它只是尝试登录数据库来检查凭据,如果失败则抛出AuthenticationExcepion。这里的权衡是你必须每次都初始化一个连接,这有一些延迟。您的领域甚至可能使用应用程序范围的连接池并检查数据库元数据以获取身份验证和授权数据。当然,这将使得有必要以特权用户身份访问数据库 - 这是一个可怕的想法。
结论:无论您采用哪种方式,通过数据库管理应用程序身份验证和授权需求都可能会消除应用程序中的身份验证和授权层,但又需要额外的抽象层(您不需要)想要更改服务的代码,以防一些数据库机制发生变化,是吗?),在我们看到并将您的代码与一个数据库联系起来时会产生可扩展性问题(当然,您不需要细粒度的权限,并且可以忍受“工作,没有工作“结果”。
答案 1 :(得分:0)
我不确定空连接池的开销是多少,也不确定涉及多少用户,但是我建议保留为低最大连接(2?)和积极空闲配置的连接池的全局列表超时一直回到零池连接。然后,当用户登录时,检查他们是否已经拥有其用户名引用的池,如果没有,则创建一个新池,并将其粘贴在池中,然后使用该池进行该用户的连接。
通过这种方式,您可以获得开销最小的池的好处。这是否可行可能取决于您的用户数量。
我当然希望找到适合您的最低开销池实现 - 有几个可供选择。 c3p0对我自己很有用。