创建数据库连接池

时间:2009-11-10 10:24:26

标签: database connection connection-pooling

需要有关创建数据库连接池的信息(无论数据库如何),以及它们的效率如何?他们可以提高绩效的条件是什么。

如何明确创建它?

7 个答案:

答案 0 :(得分:6)

你的问题有点含糊不清:

您想 homegrow 连接池实现吗?如果是这样,这是一个很好的起点:http://java.sun.com/developer/onlineTraining/Programming/JDCBook/conpool.html 这对于生产环境非常不鼓励。更好地使用现有且经过全面测试的连接池API,例如DBCPC3P0

或者您想知道如何使用连接池?如果是这样,答案取决于您正在使用的连接池API。幸运的是,通常可以在相关API的网站上找到它。

或者您想知道何时/为什么使用连接池?如果是这样,如果您拥有一个长期存在的应用程序(例如Web应用程序)并且您需要经常连接数据库,它肯定会增强连接性能。正常的JDBC实践是:获取关闭最短可能范围内的ConnectionStatementResultSet(即内部)同样的方法块)。由于连接相当昂贵,可能需要200毫秒甚至更长时间,因此使用连接池要快得多。它按需提供连接,并负责实际关闭连接。但这并不意味着您可能会改变编写JDBC的方式,您仍然需要在尽可能最大的范围内获取并关闭它们。您需要更改的唯一方法是获取连接的方式。例如。改变

connection = driverManager.getConnection();

connection = connectionPool.getConnection();

只要您的JDBC代码编写良好,就不需要进行任何更改。

答案 1 :(得分:3)

Apache DBCP的介绍页总结得很好:

  

为每个人创建一个新连接   用户可能很耗时(通常   需要多秒钟   时间),以执行数据库   可能需要的交易   毫秒。打开连接   用户在a中是不可行的   公开托管的Internet应用程序   同时用户数量   可以非常大。因此,   开发人员经常希望分享一个   所有人之间开放联系的“池”   该应用程序的当前用户。   实际用户数量   在任何给定时间执行请求   通常只是一小部分   活跃用户总数,以及   在请求处理期间是唯一的   数据库连接的时间   需要。应用程序本身记录   进入DBMS,并处理任何用户   内部帐户问题。

他们效率如何?取决于实施。通常我希望池在启动时或根据请求实例化连接。第一个连接将需要与数据库的真实连接,此后当您请求连接时,您将获得一个现有的池连接。因此,第一个连接请求将占用大部分时间,之后您只是从集合中提取对象(非常快)。

答案 2 :(得分:1)

创建与数据库的连接是非常昂贵的操作。连接池是创建和缓存的数据库连接的实例。无论何时需要与数据库建立新连接,都会使用池中的一个连接,而不是创建新连接。某些平台(如.NET + SQL Server)默认使用连接池(您无需创建自己的连接池)。因此,它们通过每次创建新连接节省时间,基本上提高了性能。

答案 3 :(得分:1)

使用连接池可以节省每次访问的时间,因为已建立连接。

此外,至少在Oracle上,您保持编译语句链接到连接,因此重复执行相同的SQL语句甚至更快。

(如果您使用的是Java / JDBC,请参阅PreparedStatement)

反击性能的唯一风险是当您在池中保留太多空闲连接时,相关的资源(您的身边和数据库)都会被浪费。

答案 4 :(得分:1)

在某些数字的基准测试部分中查看BoneCP(http://jolbox.com)。请记住,preparedStatements等与连接相关联,因此如果您自己处理连接,则需要一次又一次地准备它们(连接池也会为您缓存这些连接)。

到目前为止我的最佳解决方案:使用一个lazyDataSource,它只在你真正需要时才提供连接(即不是盲目的 - 如果数据可以来自缓存,那么你可以避免数据库命中)

答案 5 :(得分:1)

使用tomcat创建数据库连接池

<强> 1。 Tomcat在里面输入资源:conf / context.xml

将资源条目放在context.xml文件中:

<!-- jdbc/jndiName jndi --> 
<Resource name="jdbc/jndiName" auth="Container" type="javax.sql.DataSource" initialSize="1" maxActive="100" maxIdle="30" maxWait="10000" username="enter username" password="enter password" driverClassName="diver name" url="jdbc database url"/>

<强> 2。创建一个将创建连接池的类

public class MyConnectionFactory {
    private static String module = "[ QuoteConnectionFactory ]";
    private static QuoteConnectionFactory connectionFactory;

    protected QuoteConnectionFactory() {
    }

    /**
     *
     * @return=>getInstance() is a static method which will return the instance
     *                        of its own class
     */
    public static QuoteConnectionFactory getInstance() {
        if (connectionFactory == null)
            connectionFactory = new QuoteConnectionFactory();
        return connectionFactory;
    }

    /**
     *
     * @param jndiName

     */
    public Connection getConnection(String jndiName) {
        System.out.println("jndiName=======" + jndiName);
        Connection conn = null;
        InitialContext cxt = null;
        DataSource dataSource = null;
        try {
            cxt = new InitialContext();
            Context envContext  = (Context)cxt.lookup("java:/comp/env");
            dataSource = (DataSource)envContext.lookup(jndiName);
        } catch (NamingException e) {

        } catch (Exception e) {

        }

        if (dataSource == null) {

            try {
                conn = dataSource.getConnection();
            } catch (Exception e) {

            }

            System.out.println("connection===================" + conn);
            return conn;
        }
    }

第3。编辑web.xml文件

<resource-ref>
    <description>DB Connection</description>
    <res-ref-name>jdbc/jndiName</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
</resource-ref>

<强> 4。在代码中使用

Connection con= QuoteConnectionFactory.getInstance(). getConnection("jndiName");

答案 6 :(得分:0)

创建数据库连接可能是也可能不是一项昂贵的操作,具体取决于您的环境以及您打算如何处理它。

如果您要运行一个非常简单的查询,那么连接可能需要与查询一样长(或更长)。

某些数据库的连接开销比其他数据库大得多;如果调整正确,mysql应该很少(超过时间进行tcp连接并进行协议握手)。但是,如果服务器的延迟非常高,即使这样也非常重要(特别是如果您打算只进行一些查询)。

如果你打算做100个查询,或者几个非常慢的查询,那么连接时间就会消失得无足轻重。

通常我会说每次都要打开一个新连接,直到你能证明这是一个真正的性能问题。使用连接池可能导致BUGS,我们不喜欢:

  • 上次在池中使用后,连接状态未完全重置 - 因此某些状态会导致意外行为并导致出现错误
  • 以某种方式关闭连接(可能是通过状态防火墙超时)无法检测到,因此应用尝试使用已关闭的连接,导致长时间延迟或失败