文档章节

JNDI与JDBC比较以及连接池的技术

sjzmlb
 sjzmlb
发布于 2015/05/11 18:01
字数 2023
阅读 23
收藏 0
       Java Database Connectivity(JDBC)JDBC 以一种统一的方式来对各种各样的数据库进行存取。和 ODBC 一样, JDBC 为开发人员隐藏了不同数据库的不同特性。另外,由于 JDBC 建立在 Java 的基础上 , 因此还提供了数据库存取的平台独立性。 JDBC 定义了 4 种不同的驱动程序: JDBC-ODBCBridge JDBC-native driverbridge JDBC-networkbridge PureJavadriver 。在一个多层的企业级应用中,更大的可能是在客户端和一个 EJB 进行通信,采用 EJB 建立数据库连接。为了实现和改进可伸缩性和系统性能, 也可以采用连接缓冲池( connection pool )优化数据库连接。

Java Naming and Directory Interface (JNDI)JNDI API被用于执行名字和目录服务。它提供了一致的模型来存取和操作企业级的资源如DNSLDAP,本地文件系统,后者在应用服务器中的对象。在JNDI中,在目录结构中的每一个结点称为context。每一个JNDI名字都是相对于context的。应用可以通过这个初始化的context经有这个目录树来定位它所需要的资源或对象。

JNDI相对与JDBC来说是他的灵活性,程序员不需要关心“具体的数据库后台是什么?JDBC驱动程序是什么?JDBC URL格式是什么?访问数据库的用户名和口令是什么?”等等这些问题,程序员编写的程序应该没有对 JDBC 驱动程序的引用,没有服务器名称,没有用户名称或口令 —— 甚至没有数据库池或连接管理。而是把这些问题交给J2EE容器来配置和管理,程序员只需要对这些配置和管理进行引用即可。

理解连接池

连接池是创建和管理多个连接的一种技术,这些连接可被需要使用它们的任何线程使用。连接池技术基于下述事实:对于大多数应用程序,当它们正在处理通常需要数毫秒完成的事务时,仅需要能够访问JDBC连接的1个线程。未处理事务时,连接处于闲置状态。使用连接池,允许其他线程使用闲置连接来执行有用的任务。

事实上,当某一线程需要用JDBCMySQL或其他数据库上执行操作时,需要用到由连接池提供的连接。使用连接完成线程后,线程会将连接返回给连接池,以便该连接能够被其他需要使用连接的线程使用。

从连接池“借出”连接时,该连接仅供请求它的线程使用。从编程观点看,其效果等同于每次需要JDBC连接时调用DriverManager.getConnection(),但是,采用连接池技术,可通过使用新的或已有的连接结束线程。

连接池技术能显著增加Java应用程序的性能,同时还能降低资源使用率。连接池技术的主要优点包括:

·         缩短了连接创建时间

与其他数据库相比,MySQL提供了快速的连接设置功能,连接时间通常不是问题,但创建新的JDBC连接仍会导致联网操作和一定的IDBC驱动开销,如果这类连接是“循环”使用的,使用该方式,可避免这类不利因素。

·         简化的编程模型

使用连接池技术时,每个单独线程能够像创建了自己的JDBC连接那样进行操作,从而允许使用直接的JDBC编程技术。

·         受控的资源使用

如果不使用连接池技术,而是在每次需要时为线程创建新的连接,那么应用程序的资源使用将十分浪费,而且在负载较重的情况下会导致无法预期的结果。

注意,与MySQL的每个连接均会在客户端和服务器端造成一定的开销(每寸、CPU、关联转换等)。每个连接均会对应用程序和MySQL服务器的可用资源带来一定的限制。无论连接是否执行任何有用的任务,仍将使用这些资源中的相当一部分。

连接池能够使性能最大化,同时还能将资源利用控制在一定的水平之下,如果超过该水平,应用程序将崩溃而不仅仅是变慢。

幸运的是,Sun公司通过JDBC-2.0“可选”接口,完成了JDBC中连接池概念的标准化实施,所有主要应用服务器均实施了能够与MySQL Connector/J一起良好工作的这类API

通常,你可以在应用服务器的配置文件中配置连接池,并通过Java命名和目录接口(JNDI)访问它。在下面的代码中,介绍了在J2E应用服务器上运行的应用程序中使用连接池的方法:

示例26.12. J2EE应用服务器一起使用连接池

import java.sql.Connection;

import java.sql.SQLException;

import java.sql.Statement;

import javax.naming.InitialContext;

import javax.sql.DataSource;

public class MyServletJspOrEjb {

    public void doSomething() throws Exception {

        /*

         * Create a JNDI Initial context to be able to

         * lookup the DataSource

         *

         * In production-level code, this should be cached as

         * an instance or static variable, as it can

         * be quite expensive to create a JNDI context.

         *

         * Note: This code only works when you are using servlets

         * or EJBs in a J2EE application server. If you are

         * using connection pooling in standalone Java code, you

         * will have to create/configure datasources using whatever

         * mechanisms your particular connection pooling library

         * provides.

         */

        InitialContext ctx = new InitialContext();

         /*

          * Lookup the DataSource, which will be backed by a pool

          * that the application server provides. DataSource instances

          * are also a good candidate for caching as an instance

          * variable, as JNDI lookups can be expensive as well.

          */

        DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/MySQLDB");

        /*

         * The following code is what would actually be in your

         * Servlet, JSP or EJB 'service' method...where you need

         * to work with a JDBC connection.

         */

        Connection conn = null;

        Statement stmt = null;

        try {

            conn = ds.getConnection();

            /*

             * Now, use normal JDBC programming to work with

             * MySQL, making sure to close each resource when you're

             * finished with it, which allows the connection pool

             * resources to be recovered as quickly as possible

             */

            stmt = conn.createStatement();

            stmt.execute("SOME SQL QUERY");

            stmt.close();

            stmt = null;

            conn.close();

            conn = null;

        } finally {

            /*

             * close any jdbc instances here that weren't

             * explicitly closed during normal code path, so

             * that we don't 'leak' resources...

             */

            if (stmt != null) {

                try {

                    stmt.close();

                } catch (sqlexception sqlex) {

                    // ignore -- as we can't do anything about it here

                }

                stmt = null;

            }

            if (conn != null) {

                try {

                    conn.close();

                } catch (sqlexception sqlex) {

                    // ignore -- as we can't do anything about it here

                }

                conn = null;

            }

        }

    }

}

如上例所示,获得JNDI InitialContext并查找到数据库后,其余代码与过去在JDBC编程中使用的类似。

使用连接池时需要牢记的最重要事项是,无论在代码中出现了什么(异常、控制流等),连接以及由连接创建的任何部分(语句、结果集等)均应被关闭,以便能再次使用它们。如不然,它们将纠缠在一起,在最好的情况下,意味着它们所代表的MySQL服务器资源(缓冲区、锁定、套接字等)可能会捆绑一段时间,在最坏的情况下,可能会导致永久捆绑。

连接池的最佳大小是什么?

与所有其他配置经验规则一样,回答是“它取决于具体情况”。尽管最佳大小取决与预期的负载和平均的数据库事务时间,最佳的连接池大小小于你的预期。例如,如果使用的是Sun公司的Java Petstore Blueprint应用程序,对于包含1520个连接的连接池,使用MySQLTomcat,在可接受的相应时间下,可服务于中等程度的负载(600个并发用户)。

要想确定用于应用程序的连接池大小,应使用诸如Apache JmeterThe Grinder等工具创建负载测试脚本,并对应用程序进行负载测试。

确定出发点的一种简单方法是,将连接池的最大连接数配置为“无限”,运行负载测试,并测量最大的并发连接数。随后,应进行反向操作,确定出使应用程序具有最佳性能的连接池的最小和最大值。

本文转载自:http://www.cnblogs.com/panjun-donet/articles/1182204.html

共有 人打赏支持
sjzmlb
粉丝 7
博文 30
码字总数 2410
作品 0
海淀
程序员
Hibernate5 四种数据源配置

1.需要知道的: DBCP在hibernate3中以及不再被支持了,由于作者提出过bug,后续版本没有加入对其的支持。 推荐使用proxool,负面新闻最少的连接池 下面的图显示了,Hibernate 数据源的四种,...

---dgw博客
09/18
0
0
主流Java数据库连接池比较及前瞻

本文转载自微信公众号「工匠小猪猪的技术世界」 主流数据库连接池 常用的主流开源数据库连接池有C3P0、DBCP、Tomcat Jdbc Pool、BoneCP、Druid等 C3p0: 开源的JDBC连接池,实现了数据源和JND...

渣渣(Charles)
04/30
0
0
JVM常量池及字符串==比较分析

Java常量池技术 java中的常量池技术,是为了方便快捷地创建某些对象而出现的,当需要一个对象时,就可以从池中取一个出来(如果池中没有则创建一个),则在需要重复创建相等变量时节省了很多...

陶邦仁
2012/10/21
0
0
Hinernate中获得数据库连接池的方式及应用

Hibernate可以与任何一种java应用的运行环境集成。Java应用的运行环境可分为两种。 (1)受管理环境(Managed environment):由容器负责管理各种共享资源(如线程池和数据库连接池),以及管理...

_守望者_
2014/04/22
0
0
不断优化配置,逐步提高性能——我的一次性能测试经历

近日,合作伙伴想要针对我们的应用服务器做一个性能测试,测试的基础是伙伴原有的一个功能庞大而结构复杂的业务系统,目的是看应用服务器是否能够满足业务系统的需要,并对应用服务器做一个总...

晨曦之光
2012/03/09
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Coding and Paper Letter(三十九)

资源整理。 1 Coding: 1.Python库benchmark rio s3,用于在访问S3上的文件时对Rasterio / GDAL的多线程性能进行基准测试的工具。 benchmark rio s3 2.Pangeo-Binder Cookiecutter模板。 cook...

胖胖雕
44分钟前
2
0
Promise 对象

Promise(承诺) 的含义 Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供...

简心
46分钟前
1
0
让UI设计师崩溃的瞬间,你经历过哪些?

隔行如隔山,这句话人人耳熟能详,但其实隔行并不可怕,大家各谋其事,各尽其职,倒也互不打扰,真正可怕的是,是内行还要受外行指点江山,而最难的部分,便是那沟通。流畅的沟通,和声细语,...

mo311
48分钟前
3
0
python进制转换

#进制转换print(bin(10)) #十进制转换成二进制print(oct(10)) #十进制转换成八进制print(hex(10)) #十进制转换成十六进制print(int('1010',2)) #二进制转十进制print(int(...

fadsaa
59分钟前
13
0
syntax error near unexpected token

最近不断重复在虚拟机CentOS测试安装gitlab,因为gitlab有一个脚本需要饭强才能下载,于是我先在windows下载好再上传到虚拟机,可是执行脚本的时候提示“syntax error near unexpected toke...

W_Lu
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部