日期:2014-05-16  浏览次数:20606 次

由DBCP引出的疑惑

那天突然跟同事谈起为啥要用DBCP,顾引出下面文章,只是问题随想与资料汇总之谈

?

--TOMCAT通过DBCP提供了JNDI的实现,那么为什么要使用DBCP呢?
通过DBCP实现JNDI的主要目的是,可以通过DataSource建立数据库连接。

--那么为什么要通过DataSource链接数据库?
在JDBC 1.0中提供了DriverManager 来链接数据库,那么调用DriverManager的getConnection方法时,驱动管理器遍历所有注册过的驱动程序,以便找到一个能够使用数据库URL中指定的子协议的驱动程序。

--那么为什么JDK API中对DriverManager会有“注:DataSource 接口是 JDBC 2.0 API 中的新增内容,它提供了连接到数据源的另一种方法。使用 DataSource 对象是连接到数据源的首选方法。”这句话呢?DataSource连接数据库到底比DriverManager建立数据库连接的优势在哪里?

--什么是DataSource,在JDK API中提供的解释是:
“工厂用于提供到此 DataSource 对象所表示的物理数据源的连接。作为 DriverManager 工具的替代项,DataSource 对象是获取连接的首选方法。实现 DataSource 接口的对象通常在基于 JavaTM Naming and Directory Interface (JNDI) API 的命名服务中注册。
DataSource 接口由驱动程序供应商实现。共有三种类型的实现:
基本实现 - 生成标准的 Connection 对象
连接池实现 - 生成自动参与连接池的 Connection 对象。此实现与中间层连接池管理器一起使用。
分布式事务实现 - 生成一个 Connection 对象,该对象可用于分布式事务,大多数情况下总是参与连接池。此实现与中间层事务管理器一起使用,大多数情况下总是与连接池管理器一起使用。
DataSource 对象的属性在必要时可以修改。例如,如果将数据源移动到另一个服务器,则可更改与服务器相关的属性。其优点在于,由于可以更改数据源的属性,所以任何访问该数据源的代码都无需更改。
通过 DataSource 对象访问的驱动程序本身不会向 DriverManager 注册。通过查找操作获取 DataSource 对象,然后使用该对象创建 Connection 对象。使用基本的实现,通过 DataSource 对象获取的连接与通过 DriverManager 设施获取的连接相同。”

--在DataSource实现类型的第三点中分布式事务实现? 我联想到了J2EE 13种技术规范中的JTA

--什么是JTA?简单的说:JTA定义了一种标准的API,应用系统由此可以访问各种事务监控。
从网上找了一段JTA概述:
"JTA,即Java Transaction API,译为Java事务API。 JTA允许应用程序执行分布式事务处理——在两个或多个网络计算机资源上访问并且更新数据。JDBC驱动程序的JTA支持极大地增强了数据访问能力。
编辑本段JTA和JTS
  Java事务API(JTA:Java Transaction API)和它的同胞Java事务服务(JTS:Java Transaction Service),为J2EE平台提供了分布式事务服务(distributed transaction)。一个分布式事务(distributed transaction)包括一个事务管理器(transaction manager)和一个或多个资源管理器(resource manager)。一个资源管理器(resource manager)是任意类型的持久化数据存储。   事务管理器(transaction manager)承担着所有事务参与单元者的相互通讯的责任。
编辑本段JTA与JDBC
JTA事务比JDBC事务更强大。一个JTA事务可以有多个参与者,而一个JDBC事务则被限定在一个单一的数据库连接。下列任一个Java平台的组件都可以参与到一个JTA事务中:JDBC连接、JDO PersistenceManager 对象、JMS 队列、JMS 主题、企业JavaBeans(EJB)、一个用J2EE Connector Architecture 规范编译的资源分配器。"

--JTA怎么实现?
可以考虑使用Spring+Hibernate实现,spring支持两种事务,一种是本地连接事务,一种是JTA事务。JTA事务可以支持多种数据源,可以做分布式管理。

--在一个讨论连接多个数据库或使用分布式的帖子上看到robbin回复说“是应用服务器的职责,你需要在应用服务器上面配置XA支持的数据源,然后直接使用JTA”,JTA来管理事务我们已经了解了,那什么是XA支持的数据源?

--什么是XA 有一篇文章解释一下
XA接口标准是事务处理系统与数据库服务器的事务管理接口,CICS事务所作的数据库修改在事务提交(COMMIT)或回撤(ROLLBACK)时由事务处理器通过XA接口向数据库服务器发出提交或回撤请求。由于网络通讯故障随时可能发生,任何发出请求后等待回应的程序都会有失去联系的危险。这种危险发生在发出请求之后,服务器返回应答之前,如果在这个期间网络通讯发生故障,发出请求一方无法收到回应,于是无法判断服务器是否已经成功地处理请求,因为收不到回应可能是请求没有成功地发送到服务器,也可能是服务器处理完成后的回应无法传回请求方。这段时间称为网络通讯的危险期(In-doubt Time)。 无论如何,网络通讯危险期总是存在的,两阶段提交是为了解决这个问题的一种办法。一阶段提交就是事务处理器向数据库服务器发出提交请求,然后等待数据库服务器的回应,收到回应后完成事务的提交,或者服务器返回提交失败的结果就回撤事务。危险期从发出请求开始,到收到回应结束,这段时间中数据库完成数据的修改、日志记录等处理,处理越复杂,危险期就越长。 两阶段提交把事务提交分成两个阶段,第一阶段,事务处理器向数据库服务器发出 " 准备提交 " 请求,数据库收到请求后执行相同的数据修改和日志记录等处理,不同的是处理完成后只是把事务的状态改成 " 可以提交 " ,然后把结果返回给事务处理器。事务处理器收到回应后进入第二阶段,如果在第一阶段内的危险期中发生了故障,事务处理器收不到回应,则认为事务失败,回撤事务。数据库服务器收不到第二阶段的确认提交请求,把 " 可以提交 " 的事务回撤。 两阶段的第二阶段中事务处理器向数据库服务器发出 " 确认提交 " 请求,数据库服务器把事务的 " 可以提交 " 状态改为 " 提交完成 " 状态,然后返回应答。从严格意义上说,两阶段提交并没有完全解决网络通讯危险期的问题,但因为第二阶段的处理很简单,只是修改了事务的状态,与第一阶段相比其处理时间极短,所以危险期极短,发生事务提交故障的可能性几乎不存在。很多人会问:如果事务处理器只管理一个数据库资源,是不是可以只用一阶段提交的XA接口,如果要管理两个或以上的数据库资源就要使用两阶段提交的XA接口?答案是否定的,用不用两阶段提交不是取决于数据库资源的个数,而是取决于通讯危险期的长短,即事务处理器与数据库服务器间的网络通讯质量。如果事务处理器通过XA接口连接远程数据库,网络通讯质量不高,为了保证事务的完整性,即使只连接一个数据库也应该使用两阶段提交接口。如果事务处理通过XA接口连接局域网上的数据库服务器,连接一个或多个数据库都可以使用一阶段提交接口。 管理多个数据资源的事务处理器中发生的事务可以修改所有相连的数据库,事务提交被分解为多个子事务,分别向各个数据库发出提交请求,这种事务也被称为全局事务。管理单个数据资源的事务处理器中发生的事务只能修改一个数据库,因而不会被分解,这种事务被称为局部事务。虽然多数关于两阶段提交的资料都以全局事务的运作来说明两阶段提交的原理,但两阶段提交与全局事务并没有直接的联系。 同一个事务处理器连接的多个数据资源要使用类型相同的XA接口,不能一些使用一阶段提交接口,另一些却使用两阶段提交接口,如果这样配置,全局事务的提交会失败。两阶段提交的处理过程比一阶段提交复杂,所以效率也较低,大多数企业事务处理系统的事务处理器与数据库服务器运行在同一个计算中心内,以高速而稳定的网络相连接,甚至运行在同一台机器上,这种配置最好使用一阶段提交接口。这时会引出第二个问题:一台CICS服务器上的应用要连接一个本地的数据库(指运行在同一台机器上或连接在同一个高速的局域网上的数据库),同时也要通过不稳定的网络连接另一个远程数据库,该如何保证CICS应用执行的事务完整性?如果访问远程数据库的响应时间不会过长以至严重地影响整个事务的处理时间,仍然可以采用两阶段提交XA接口。否则应该采用另一种方案,在远程数据库一端安装一个CICS服务器与该数据库通过一阶段提交XA接口相连,本地CICS服务器上的应用要访问远程数据库时通过CICS间的互连机制向远程CICS服务器发出处理请求,由远程CICS服务器上的程序完成处理,整个事务的完整性由CICS的分布式事