每个网络用户应该在 Servlet 中单独连接到数据库,还是用户可以共享相同的连接引用?

Should each web user have separate connection to database in Servlet or users can share same connection reference?

我正在 Java 中制作一个网络应用程序,我希望用户连接到数据库。作为初学者,我遇到了术语 Connection Pooling。我了解它的主要用途,即连接可重用性。

因此,我的代码可能如下所示:

public class Test extends HttpServlet {
 
    @Resource(name = "poolName")
    private DataSource dataSource;
 
    protected void doGet(HttpServletRequest request, HttpServletResponse response) {
        Connection connection = dataSource.getConnection();
        //do some SQL with this local variable
        //every user will have its own connection
    }
 
}

但是有人可以告诉我以下内容吗?当我可以声明每个用户(线程)将使用的连接类型的实例变量时,为什么我应该在每个用户请求时从连接池获取连接?

为简化起见,当用户可以共享一个连接时,我为什么要给每个用户一个连接?代码如下:

public class Test extends HttpServlet {
 
    @Resource(name = "poolName")
    private DataSource dataSource;
    private Connection connection;
     
    public void init() {
        connection = dataSource.getConnection();
    }
     
    protected void doGet(HttpServletRequest request, HttpServletResponse response) {
        //do some SQL with referenced instance variable connection
        //every user will share same connection
    }
 
}

有人可以教我如何编写好的代码以及一种方法相对于另一种方法有哪些优势?我认为我的最后一个示例(在新请求时不从连接池获取连接)看起来更好(我觉得我错了)。

一方面,它耗尽了资源。您的应用程序与数据库建立的每个连接都是内存中的另一个项目加上您的应用程序服务器和数据库的另一个网络连接。使用连接池可确保当且仅当需要时才打开新连接。

每个连接都有自己的事务。如果你有一个共享连接,你就不能让事务跨越多个语句,因为如果你有并发用户,调用就会交错,并且无法预测事务中会发生什么。

如果每个用户都有自己的连接,每个用户都可以启动自己的事务并与其他用户分开提交,并且只包含他们需要的语句。这意味着用户的工作是在可预测的块中完成的,而不是杂乱无章的。事务是关系数据库的一个非常有用的特性,任何排除使用它们的应用程序设计都可能是一个问题。

数据库连接并不意味着被多个线程使用,即使连接是线程安全的,它也可能一次锁定除一个用户以外的所有用户。所以你的并发性会很糟糕。当有多个用户时,他们会堆积起来等待使用共享连接。如果您对一条语句的性能有疑问,那将影响所有其他正在等待的线程。

数据库连接也坏了。网络连接很脆弱,而且会出现故障。如果您使用一个连接,那么当连接出现故障时,整个应用程序将不得不重新启动。如果您使用池,它会负责创建和分发连接,而​​陈旧的连接是您的应用程序可以轻松恢复的东西。