为连接到服务器应用程序的每个客户端打开一个新的数据库连接?
Opening a new database connection for every client that connects to the server application?
我正在构建一个客户端-服务器应用程序,我真的很想得到有关如何设计服务器-数据库连接部分的建议。
假设基本思想如下:
- 客户端在服务器上验证自己。
- 客户端向服务器发送请求。
- 服务器将客户端的请求存储到本地数据库。
就 Java 个对象而言,我们有
- 客户端对象
- 服务器对象
- 数据库对象
因此,当客户端连接到服务器时,会在它们之间创建一个会话,通过该会话交换所有数据。现在困扰我的是我是否应该为每个客户端会话创建一个数据库object/connection,或者我是否应该创建一个数据库对象来处理所有请求。
因此这两个概念是
- 创建一个处理所有客户端请求的数据库对象
- 为每个客户端-服务器会话创建一个专供客户端使用的数据库对象。
选择选项 1,我想所有方法都应该同步以避免一个客户端线程不覆盖另一个的变量。但是,在有大量并发请求的情况下,使其同步将非常耗时,因为每个请求都将放入队列中,直到 运行 完成。
选择选项 2,似乎是更合适的解决方案,但为每个客户端-服务器会话创建数据库对象是一项耗费内存的任务,另外还要为每个客户端创建数据库连接当并发连接的用户数很大时,可能会再次出现问题。
这些只是我的想法,所以请添加任何可能有助于做出决定的评论。
谢谢
方案三:使用连接池。每次你想连接到数据库时,你都会从池中获得一个连接。完成后,关闭连接以将其返回到池中。
这样你就可以
- 有多个客户端同时访问数据库(您的选项 1 不允许这样做)
- 打开合理数量的连接并避免使数据库瘫痪或 运行 可用连接不足(您的选项 2 不允许这样做)
- 避免一直打开新的数据库连接(您的选项 2 不允许这样做)。打开连接是一项代价高昂的操作。
基本上所有的服务端应用都采用这种策略。所有 Java EE 服务器都带有一个连接池。您还可以在 Java SE 应用程序中使用它,方法是将池用作库(HikariCP、Tomcat 连接池等)
只需使用连接池并选择选项 2。有很多 - C3P0、BoneCP、DBCP。我更喜欢 BoneCP。
我会建议第三种选择,数据库连接池。通过这种方式,您可以创建指定数量的连接,并在第一个可用的免费连接可用时立即发出。这为您提供了两全其美的优势——几乎总是可以快速使用免费连接,并且您可以将数据库的连接数保持在合理的水平。有很多现成的 java 连接池解决方案,因此请在线查看。
两者都不是很好的解决方案。
选项 1 有问题:
您已经说明了多线程时同步的问题。但除此之外还有许多其他问题,如事务管理(你什么时候提交连接?)、安全性(所有客户端都可以看到预先提交的值).. 仅举几例..
选项 2 有问题:
两个最大的问题是:
- 每次创建新连接都需要很多时间。所以性能会成为问题。
- 数据库连接是极其昂贵的资源,应限制使用数量。如果您开始为每个客户端创建数据库连接,您很快就会 运行 脱离它们,尽管大多数连接不会被主动使用。您还会看到您的应用程序性能下降。
连接池选项
这就是几乎所有客户端-服务器应用程序都采用连接池解决方案的原因。您在池中有一组连接,这些连接会被适当地获取和释放。几乎所有 Java 框架都有复杂的连接池解决方案。
如果您没有使用任何 JDBC 框架(大多数使用 Spring JDBC\Hibernate),请阅读以下文章:
http://docs.oracle.com/javase/jndi/tutorial/ldap/connect/pool.html
如果您正在使用任何流行的 Java 框架,例如 Spring,我建议您使用框架提供的连接池。
我正在构建一个客户端-服务器应用程序,我真的很想得到有关如何设计服务器-数据库连接部分的建议。 假设基本思想如下:
- 客户端在服务器上验证自己。
- 客户端向服务器发送请求。
- 服务器将客户端的请求存储到本地数据库。
就 Java 个对象而言,我们有
- 客户端对象
- 服务器对象
- 数据库对象
因此,当客户端连接到服务器时,会在它们之间创建一个会话,通过该会话交换所有数据。现在困扰我的是我是否应该为每个客户端会话创建一个数据库object/connection,或者我是否应该创建一个数据库对象来处理所有请求。
因此这两个概念是
- 创建一个处理所有客户端请求的数据库对象
- 为每个客户端-服务器会话创建一个专供客户端使用的数据库对象。
选择选项 1,我想所有方法都应该同步以避免一个客户端线程不覆盖另一个的变量。但是,在有大量并发请求的情况下,使其同步将非常耗时,因为每个请求都将放入队列中,直到 运行 完成。
选择选项 2,似乎是更合适的解决方案,但为每个客户端-服务器会话创建数据库对象是一项耗费内存的任务,另外还要为每个客户端创建数据库连接当并发连接的用户数很大时,可能会再次出现问题。
这些只是我的想法,所以请添加任何可能有助于做出决定的评论。
谢谢
方案三:使用连接池。每次你想连接到数据库时,你都会从池中获得一个连接。完成后,关闭连接以将其返回到池中。
这样你就可以
- 有多个客户端同时访问数据库(您的选项 1 不允许这样做)
- 打开合理数量的连接并避免使数据库瘫痪或 运行 可用连接不足(您的选项 2 不允许这样做)
- 避免一直打开新的数据库连接(您的选项 2 不允许这样做)。打开连接是一项代价高昂的操作。
基本上所有的服务端应用都采用这种策略。所有 Java EE 服务器都带有一个连接池。您还可以在 Java SE 应用程序中使用它,方法是将池用作库(HikariCP、Tomcat 连接池等)
只需使用连接池并选择选项 2。有很多 - C3P0、BoneCP、DBCP。我更喜欢 BoneCP。
我会建议第三种选择,数据库连接池。通过这种方式,您可以创建指定数量的连接,并在第一个可用的免费连接可用时立即发出。这为您提供了两全其美的优势——几乎总是可以快速使用免费连接,并且您可以将数据库的连接数保持在合理的水平。有很多现成的 java 连接池解决方案,因此请在线查看。
两者都不是很好的解决方案。
选项 1 有问题:
您已经说明了多线程时同步的问题。但除此之外还有许多其他问题,如事务管理(你什么时候提交连接?)、安全性(所有客户端都可以看到预先提交的值).. 仅举几例..
选项 2 有问题:
两个最大的问题是:
- 每次创建新连接都需要很多时间。所以性能会成为问题。
- 数据库连接是极其昂贵的资源,应限制使用数量。如果您开始为每个客户端创建数据库连接,您很快就会 运行 脱离它们,尽管大多数连接不会被主动使用。您还会看到您的应用程序性能下降。
连接池选项
这就是几乎所有客户端-服务器应用程序都采用连接池解决方案的原因。您在池中有一组连接,这些连接会被适当地获取和释放。几乎所有 Java 框架都有复杂的连接池解决方案。
如果您没有使用任何 JDBC 框架(大多数使用 Spring JDBC\Hibernate),请阅读以下文章: http://docs.oracle.com/javase/jndi/tutorial/ldap/connect/pool.html
如果您正在使用任何流行的 Java 框架,例如 Spring,我建议您使用框架提供的连接池。