background image

4   DataSource db1 = (DataSource) ic.lookup("java:comp/env/OrdersDB");
5   DataSource db2 = (DataSource) ic.lookup("java:comp/env/InventoryDB");
6   Connection con1 = db1.getConnection();
7   Connection con2 = db2.getConnection();
8   // perform updates to OrdersDB using connection con1
9   // perform updates to InventoryDB using connection con2
10   ut.commit();
11

 

  注意,这个示例中没有征用当前事务中 JDBC 

   

连接的代码 ― 容器会为我们完成这个

任务。我们来看一下它是如何发生的。

  资源管理器的三种类型

 

  当一个 EJB 组件想访问数据库、消息队列服务器或者其它一些事务性资源时,它需
要到资源管理器的连接(

 

通常是使用 JNDI)。而且,J2EE 规范只认可三种类型的事务性资

   

源 ― JDBC 数据库、JMS 

 

消息队列服务器和 其它通过 JCA 

访问的事务性服务 。后面一种

服务(

 

比如 ERP 系统)

 

必须通过 JCA(J2EE Connector Architecture,J2EE 连接器体系结构)访

问。对于这些类型资源中的每一种,容器或提供者都会帮我们把资源征调到事务中。

 

    在 清 单 1  

 

中 , con1  

 

和 con2  

 

好 象 是 普 通 的 JDBC   连 接 , 比 如 那 些 从 

DriverManager.getConnection() 

 

返回的连接。我们从一个 JDBC DataSource 得到这些连接,

JDBC DataSource 

 

可以通过查找 JNDI 中的数据源名称得到。EJB 组件中被用来查找数据源

( java:comp/env/OrdersDB )的名称是特定于组件的;

 

组件的部署描述符的 resource-ref 部分

 

将其映射为容器管理的一些应用程序级 DataSource   

的 JNDI 名称。

 

  隐藏的 JDBC 驱动器

 

  每个 J2EE 

 

容器都可以创建有事务意识的池态 DataSource 

 

对象,但 J2EE 规范并不向

 

您展示如何创建,因为这不在 J2EE 

 

规范内。浏览 J2EE 文档时,您找不到任何关于如何

 

创建 JDBC 数据源的内容。相反,您不得不为您的容器查阅该文档。创建一个数据源可能

 

需要向属性或配置文件添加一个数据源定义,或者也可以通过 GUI 管理工具完成,这取
决于您的容器。

  每个容器(

 

或连接池管理器,如 PoolMan)

 

都提供它自己的创建 DataSource 机制,JTA 

 

魔术就隐藏在这个机制中。连接池管理器从指定的 JDBC 

 

驱动器得到一个 Connection ,但

 

在将它返回到应用程序之前,将它与一个也实现 Connection 的虚包包在一起,将自己置

 

入应用程序和底层连接之间。当创建连接或者执行 JDBC 操作时,包装器询问事务管理器

 

当前线程是不是正在事务的上下文中执行,如果事务中有 Connection 的话,就自动征用
它。

其它类型的事务性资源,JMS 

 

消息队列和 JCA 连接器,依靠相似的机制将资源征用