Java 不带连接池的Web应用程序的数据库连接

Java 不带连接池的Web应用程序的数据库连接,java,web-applications,jdbc,Java,Web Applications,Jdbc,我正在尝试一种从JSFWeb应用程序建立到数据库的JDBC连接的正确方法。解决这个问题的通常方法是在应用服务器中创建一个数据源,并通过代码中的JNDI名称连接到它。实际上,所有用户在整个会话期间都将通过池共享相同的数据库用户帐户 不幸的是,我正在从事的一个新项目的要求阻止了我这样做。每个连接到应用程序的用户都必须使用唯一的凭据登录到RDBMS。我有一个如何实现与此相关的代码的草图,但我对整个体系结构不是100%清楚。 应用服务器(Tomcat、Glassfish、WebLogic)是否具有支持此

我正在尝试一种从JSFWeb应用程序建立到数据库的JDBC连接的正确方法。解决这个问题的通常方法是在应用服务器中创建一个数据源,并通过代码中的JNDI名称连接到它。实际上,所有用户在整个会话期间都将通过池共享相同的数据库用户帐户

不幸的是,我正在从事的一个新项目的要求阻止了我这样做。每个连接到应用程序的用户都必须使用唯一的凭据登录到RDBMS。我有一个如何实现与此相关的代码的草图,但我对整个体系结构不是100%清楚。 应用服务器(Tomcat、Glassfish、WebLogic)是否具有支持此功能

现在,完成这一任务的唯一方法似乎是让每个用户会话直接创建一个返回数据库的JDBC连接。虽然我相信这会管用,但感觉不太对劲


我是否遗漏了什么?

我不确定空连接池的开销是多少,也不确定涉及多少用户,但我建议保留一个全局连接池列表,配置为低最大连接数(2?)和积极的空闲超时,直到池连接数为零。然后,当用户登录时,检查他们是否已经有一个由用户名引用的池,如果没有,则创建一个新池并将其粘贴到池中,然后将该池用于该用户的连接

这样,您可以以最少的开销获得池的好处。这是否可行可能取决于您的用户数量


我当然希望找到对您来说功能性的最低开销池实现——有几种可供选择。c3p0对我来说工作得很好。

你错过了一些东西——我认为这是非常重要的:合理的系统设计。;)使用用户的数据库凭证管理用户的整个思想只适用于一个用例imho-管理数据库。对于其他一切,它带来的问题比它带来的好处多。。。所以,让这场灾难开始吧……;)

机器人:这是一个进退两难的问题。基本上,您必须为每个用户创建一个连接池,因为否则每次数据源在连接超时时都必须创建到数据库的连接。三方握手加身份验证并不是一件便宜的事情——延迟会降低性能。虽然可以相应地配置一些驱动程序,但这通常是一个坏主意,因为所谓的“关注点分离”,大多数驱动程序本身并不擅长管理连接。另一方面,每个连接“池”只需要大约5个连接,因为同一用户不太可能并行执行许多操作

注意:我所知道的唯一一个能够以正统方式管理连接和池的驱动程序是MongoDB的驱动程序

现在问题来了:您不能将连接池附加到会话。不走几英里就不行,我怀疑这完全是可能的

解决这个问题的一个方法是在用户登录时为其创建一个连接池,并向JNDI动态注册。问题是,这不是非常可伸缩的(假设您有数百个用户)。因此,您必须确保在会话终止时(通过注销或超时)删除池。此外,还必须维护代码

另一个想法是使用并编写一个自定义域,该域仅尝试登录数据库以检查凭据,如果失败,则抛出AuthenticationExcepion。这里的折衷是,您每次都必须初始化一个连接,这会有一些延迟。您的领域甚至可能使用应用程序范围的连接池,并检查数据库元数据以获取身份验证和授权数据。当然,这就需要以特权用户的身份访问数据库——这是一个可怕的想法


一句话:无论从哪个角度看,通过数据库管理应用程序的身份验证和授权需求可能会消除应用程序中的身份验证和授权层,但反过来又需要额外的抽象层(如果某些数据库机制发生变化,您不想更改服务的代码,是吗?),正如我们所看到的,这会带来可伸缩性问题,并将您的代码与一个数据库绑定在一起(当然,您不希望获得细粒度的权限,并且可以接受“已工作,未工作”的结果).

有趣的方法。由于保证每个用户都有100%唯一的用户名,我可能需要在注销时销毁池。感谢您的建议!您可能需要检查从中获得的连接是否已被池化(我看到有池和没有池)。非常感谢您的回复!这些问题与我在提出需求时所关心的问题完全相同。我当前的想法(再次强调,我意识到这并不理想…)是配置一个非常小的池,用于读取RDBMS中用户创建的一组表以检查凭据(而不是,例如Oracle中的dba_用户视图)。一旦检查了creds,应用程序将创建一个会话。从那里,将仅为该用户创建另一个连接,并使用他/她自己的RDBMS凭据。我认为这太多的代码无法维护。我宁愿使用Shiro和自定义域,这很容易实现。