面向数据库管理员的J2EE

与J2EE开发人员进行对话时,数据库管理员需要了解的内容。

如果你是一个与Java开发人员协同工作的Oracle数据库管理员,你可能与他们有很多不同的看法。例如,当他们想改变数据库模式以更好地存储他们的对象时,你可能会很惊讶;当他们讨论WAR和EAR时,你可能会感到很困惑。为了更好地帮助你与J2EE开发人员进行沟通,让我们来对J2EE进行一个简要介绍并看看J2EE开发人员所面临的一些挑战。

什么是J2EE?

Java 2 Platform, Enterprise Edition(J2EE)是一个构建和实施可移植的、高度可伸缩的企业应用程序的开放标准。J2EE定义了一个开发和部署多层应用程序的平台。包括BEA、IBM、Oracle和Sun在内的几家供应商都通过提供符合J2EE标准的应用服务器来支持J2EE。用非专业的语言来说,应用服务器充当着用户和数据库管理系统之间的中间层,提供一个构建和部署企业应用程序的框架。

J2EE由几个组件组成。目前的版本J2EE 1.3包括Java Servlets 2.3、JavaServer Pages(JSP)1.2、Enterprise JavaBeans(EJB)2.0、Java Message Services(Java消息服务)1.0.2、Java Transaction API 1.0、Java Database Connectivity(Java数据库连接,JDBC)2.0、J2EE Connector Architecture(J2EE 连接器体系结构)1.0、Java Naming and Directory Interface(Java命名和目录接口,JNDI)和JavaMail 1.2等组件。

让我们更详细地了解一下数据库管理员感兴趣的那些技术。

JDBC:数据库的入口点

以与Oracle技术使用SQL*Net协议相同的方式,Java应用程序能够使用Java数据库连接(JDBC)应用编程接口(API)来连接数据库(如Oracle数据库)。作为核心的J2EE技术之一,JDBC被绝大多数的J2EE应用程序所使用,这些应用程序包括servlet、JSP和EJB。JDBC使应用程序开发人员能够将SQL语句嵌入到他们的Java代码中,以访问和更新数据库。

使用JDBC帮助Java开发人员连接"对象范例",他们通常用这些对象范例来对关系数据库进行操作。面向对象的范例支持从拥有数据和行为的对象构建应用程序。关系数据库技术支持通过SQL调用将数据存储在表中并对这些数据进行操作。

为了加快J2EE应用程序的数据库连接速度,Oracle9i应用服务器(Oracle9iAS)提供了连接共享功能。在过去,开发人员在应用程序中对用户ID和密码进行硬编码,或者将属性文件与他们部署的应用程序打包在一起。JDBC 2.0扩展通过将用户ID和密码存储在一个应用服务器配置文件中,从而使应用程序具有可移植性。开发人员可以查看DataSource对象并建立一个连接。这意味着,作为一个数据库管理员,如果要改变一个模式用户的密码,你可能必须与应用服务器管理员相互配合来进行这一改变。

对不同的应用服务器有几种不同的JDBC驱动程序,但是,作为一个Oracle数据库管理员,你可能主要对两种通用类型的驱动程序感兴趣:Type IV(或者称为众所周知的"瘦"驱动程序)和Type II(即众所周知的Oracle Call Interface(Oracle调用接口)驱动程序或称为"胖"驱动程序)。瘦驱动程序是纯粹用Java编写的,与JDBC驱动程序类文件classes12.jar协同使用。胖驱动程序使用OCI库,运行在SQL*Net之上。Oracle9iAS通过了这些类型驱动程序的认证。OCI驱动程序能够利用Net8(Oracle的网络连接技术)中的Oracle特有的一些高可用性扩展功能。Oracle9iAS不仅能够与Oracle数据库协同工作,而且也通过了诸如DB2、MS SQLServer和Sybase等第三方数据库的认证。你可以从Oracle技术网站(OTN)下载能够将Oracle9iAS 连接到这些数据库的DataDirect JDBC 驱动程序。

Servlet:CGI的替代品

与被下载到浏览器的Java applet不同,Java servlet驻留在服务器上,可以被用于访问服务器端的资源,例如业务逻辑等。servlet可以对存储在一个数据库或来自多个数据源的数据进行操作。作为杰出的服务器端Web技术,Java servlet实际上已经替代了通用网关接口(CGI)脚本,因为servlet能够提供更好的性能,并被多个供应商所支持。JSP通过允许将Java代码段嵌入到HTML文件中对Java技术进行了补充,从而改善了Web设计人员和Java编程人员之间的劳动分工。当用户调用时,JSP代码能够被自动编译并转换为Java servlet。

决大多数机构通过使用一个持久性层(例如Oracle9iAS TopLink)或者编写将其对象持久保存在数据库中的代码,来构建只带有servlet和JSP代码的商务应用程序。作为数据库的保护者,你应该仔细检查这些Java程序员在其程序中用来进行查询和数据操作的SQL语句,并确保他们的SQL语句不会产生严重的后果--例如,进行会影响生产数据库中数百万条记录的全表扫描。

The lifecycle of an entity bean

图1:实体bean的生命周期 (参见表1中的描述)
 

表1:实体bean方法

方法操作这对作为数据库管理员的你意味着什么
ejbLoad() 装载bean实例。 通常使用一个SELECT语句从数据库中检索行。
ejbCreate()创建bean实例。通过将一行插入数据库来使bean持久保存。
ejbPostCreate()在bean中设置关系域的值。通常使用一个UPDATE语句设置外部关键字域。
ejbStore()更新数据库中相应的bean。通常使用一个SELECT for UPDATE或者UPDATE 语句来更新实体bean 实例。
findByXXX()根据某个确定的条件查找bean。通常使用一个SELECT语句来取出(fetch)一行或多行。
ejbRemove()删除bean 实例。从数据库表中删除相应的行。

EJB:应用程序的逻辑

EJB是运行在EJB容器内部的Java应用程序的一个可重用组件,可以通过Java程序或CORBA客户端本地或远程地进行调用。因为EJB在一个提供对事物、持久性和bean访问控制的支持等服务的容器中执行,所以开发人员不必开发这些服务。有3种类型的EJB:会话bean、实体bean和消息驱动bean(message-driven bean,MDB)。会话bean描述那些本质上是瞬时的、且不能在机器或服务器故障中幸免的业务逻辑。会话bean有两种类型:无状态的和有状态的。无状态的会话bean不保留会话之间的任何状态--例如,哪个会话使一个无状态的会话bean成为信用卡记账的较好选择。然而,有状态的会话bean能够保留会话或方法调用之间的状态--所以有状态的会话bean适合于描述一个用于购物车的业务逻辑。会话bean可以通过使用JDBC连接到一个数据库。

实体bean:提供持久性

对数据库管理人员来说,实体bean是有吸引力的、而又有难度的,因为它们是持久的且需要一个外部数据库(例如Oracle数据库)。作为实体bean的一种替代方式,一些机构可能决定使用一个持久性层(例如Oracle9iAS TopLink)或者在内部开发用于将数据持久保存在数据库中的代码。然而,实体bean在某些情况下是非常有用的。例如,一个实体bean可能表示客户表中的一行或雇员表中的一条雇员记录。实体bean在多个客户机间也是可共享的。例如,一个Employee(雇员)实体bean可以被多个不同的客户端所使用来计算年薪或修改雇员地址。EJB服务器故障能够导致一个事务的回滚,但是不会毁坏实体bean,因为实体bean是对来自数据库中的永久数据的表示。可以通过从持久存储器读取数据来重建同一个实体bean。如同数据库记录一样,实体bean是由它的主关键字惟一标识的。(参见图1中对实体bean生命周期及其方法的描述。)

EJB规范定义了两种类型的实体bean:由bean管理持久性(BMP)的bean和由容器管理持久性(CMP)的bean。对于BMP bean来说,bean开发人员在他们的bean中编写SQL代码来创建、修改和删除你的数据库中的数据。所以当你的Java编程人员在使用BMP bean时,你一定要知道!你应该查看他们所有的SQL语句,以确保finder方法拥有使用索引的SQL语句--否则,你将必须以使用会减慢数据库速度的全表扫描而告终。

CMP bean需要你的极大关注。在CMP中,容器生成所有的SQL语句,所以你依赖应用服务器软件的开发人员来为你生成正确的SQL语句。当CMP bean被部署到Oracle9iAS时,持久数据能够被容器自动映射到一个特定的数据库表。这可能与其他应用服务器或"容器"的情况不同。对于一个Oracle数据库管理员来说,这可能是一个需要关注的问题,因为绝大多数应用服务器(包括Oracle9iAS)都使用专有算法来生成表名。这样,你就必须与开发人员进行合作,以便将实体bean映射到正确的模式。

bean开发人员必须在部署描述符中为CMP bean定义主关键字,并将该bean映射到基本表中适当的列。如果没有为一个CMP bean指定主关键字,容器将把一列添加到表中,用作主关键字。Oracle9iAS将该列命名为autoid。如果你不知道这一情况,当你在你的数据模型中发现一个不必要的列时,你将感到非常惊讶。J2EE容器(例如,Oracle9iAS)使用它自己的算法为该列生成惟一的值。

CMR(容器管理关系)是开发人员创建实体之间的关系以及J2EE应用服务器管理这些关系的地方。以Department和 Employees两个实体为例,考虑它们之间可能的各种不同关系。它们的关系可以是1对1、1对多或者多对多的,可以是单向或双向的。Oracle9iAS通过使用现有的外部键约束或一个第三方表(众所周知的结合表)来管理关系。(多对多关系只能使用结合表来管理。)默认情况下,容器将生成和命名它自己的表以维护实体关系--这些表对数据库管理员产生了一些问题。

你要记住,创建带有关系的实体bean需要分两步走:第一步创建bean,第二步创建关系。如果你有一个使用强制外部键的关系,那么你将必须在你的数据库中将该外部键列标记为"deferrable(可延迟的)"。

EJB QL与 SQL 的比较

EJB QL是J2EE 1.3中引入的一个标准查询语言,用于查询CMP bean。EJB QL通过CMP定义实体bean的各种不同的finder和select方法。开发人员/部署人员必须在bean的部署描述符中指定EJB QL语句,容器通常在运行时将EJB QL转换为SQL。EJB QL与ANSI SQL类似,但在范围上是有限的,它缺乏对Date(日期)函数和ORDER BY子句的支持。参见表2所列举的EJB QL语句及其所转换的SQL语句的例子。

表2:一个EJB QL语句及其相应的SQL语句

EJB QL语句所生成的SQL语句
SELECT OBJECT(e)
FROM Employee e WHERE e.empNo = ?1
Select *
From emp where empno= &1

关于事务所需要了解的内容

J2EE应用服务器允许EJB事务是声明性(应用程序开发人员不必编写事务逻辑代码)或编程性的。一般来说,J2EE事务长期存在并将跨越用户交互。像数据库事务一样,EJB事务必须遵从ACID(Atomic, Consistent, Isolated, and Durable,即原 子 性、 一 致 性、 孤 立 性、 耐 受 性)。对于一个声明性EJB事务(或者众所周知的由容器管理的事务(CMT))来说,bean开发人员必须指定事务属性。表3列出了事务属性的不同类型。

表3: EJB事务的属性

事务属性描述
需要(Required)如果存在一个事务,bean将连接它;否则,bean将开始一个新的事务。
需要新事务(RequiresNew)当bean 被调用时,将开始一个新的事务。
支持(Supports)如果存在一个事务,bean将连接它;否则,也不开始新事务。
不支持(NotSupported)bean 不能参与一个事务。
强制(Mandatory)总是需要一个事务;否则,它将产生一个异常。
从不(Never)如果使用这一属性并在一个事务上下文环境中调用bean,将产生一个异常。

J2EE也支持分布式事务或资源之间的两阶段提交。Oracle9iAS现在使用Oracle9i数据库作为EJB两阶段提交协调器,并要求建立一个数据库连接。

J2EE还使你能够根据表4中的信息为EJB指定不同的隔离级别。

表4: EJB 的隔离级别

隔离级别描述
读未提交(Read uncommitted)当使用这一隔离级别时,如果你的事务与另外一个事务并发执行、且其他事务将数据写入数据库而不提交,那么你的事务将能够读取这些数据。这一隔离级别对性能是有利的,但是可能会产生诸如脏读取(dirty read)、不可重复读和假读取(phantom read)等问题。
读已提交(Read committed)当使用这一隔离级别时,你的事务将不读取未提交的数据,所以你能够解决脏读取的问题。但是还将存在不可重复读和假读取等问题。
可重复读(Repeatable read)当使用这一隔离级别时,无论你什么时候读取已提交的数据,都可以确保在以后的日期再次重复读取同样的数据时具有相同的值。但仍然会存在脏读取的问题。
可串行化(Serializable)这一隔离级别能够确保所有事务串行化执行。它避免了所有的问题,但是会使性能有所降低。

表4所提出的那样,你必须决定对你的机构来说,性能和数据一致性哪个更重要。作为一个数据库管理员,你可能倾向于数据一致性,从而希望为关键系统使用可串行化选项。EJB隔离模式通常取决于哪个隔离级别被底层数据源所支持。在Oracle8i 数据库和Oracle9i数据库中,所支持的是读已提交(read-committed)隔离级别和可串行化(serializable)隔离级别。

除了EJB隔离模式外,几个应用服务器还提供了用于CMP bean并发控制的锁定模式。表5显示了Oracle9iAS中可用的不同锁定模式。这些模式与可串行化隔离级别和读已提交隔离级别结合在一起,提供了许多不同的并发策略。

表5: 在Oracle9iAS中控制CMP并发性

Oracle9iAS实体 bean锁定模式描述
乐观(Optimistic)多个用户可以并行执行实体bean。这种模式不监控资源争用情况;因此,监控数据一致性的责任交给了数据库隔离模式。
只读(Read-only)多个用户可以并行执行实体bean。容器不允许对bean的状态进行任何修改。
悲观(Pessimistic)这种模式管理资源争用,不允许并行执行。一次只允许一个用户执行实体bean。

为了获取更好的性能,你希望选择乐观(optimistic)锁定模式或只读(read-only)锁定模式。

使用消息传递产品

Oracle9iAS能够与诸如MQ Series、Sonic MQ和Swift MQ等消息提供者一起工作。如果你的开发人员正在使用Java,那么他们可能希望使用Java消息服务(Java Message Service ,JMS),JMS是由Sun、Oracle和其他企业消息产品供应商联合开发的用于企业消息传递的业界Java标准。JMS提供一个用于存储和检索异步消息的API,并对由Java远程方法调用(Java Remote Method Invocation ,RMI)所确定的同步通信模式进行了补充。Oracle的JMS实现-- OracleJMS provider是基于高级排队(Advanced Queuing ,AQ)的。Oracle Advanced Queuing(Oracle AQ)将消息作为数据库记录存储在表中,这提供了消息的安全性、可恢复性和保证传递性。Oracle的JMS实现是JMS规范的一个超集,具有支持AQ管理性操作和其他不是目前JMS标准一部分的AQ特性的扩展。这包括一个自动将消息传播到使用其他消息提供者的遗留应用程序(或者从遗留应用程序传播消息)的消息传递网关。

作为一个Oracle数据库管理员,使用OracleJMS意味着你必须安装和配置Oracle AQ,并创建由每个应用程序所使用的队列和主题。如果你计划使用支持消息驱动bean(MDB)的Oracle AQ,那么你就必须使用Oracle9i 9.0.1.4 或9.2.0.2版本。

例如,如果你的应用程序需要一个在SCOTT模式中称为theTopic的主题,那么你需要进行以下工作:

授予SCOTT操作Oracle AQ的适当权限:

grant execute on sys.dbms_aqadm to SCOTT;

grant execute on sys.dbms_aq to SCOTT;
grant execute on sys.dbms_aqin to SCOTT;
grant execute on sys.dbms_aqjms to SCOTT;

在Oracle数据库中创建队列表和主题,创建并开始theTopic:

connect SCOTT/TIGER@mydb;


BEGIN
  DBMS_AQADM.CREATE_QUEUE_TABLE(
    Queue_table => 'QT_Topic',
    Queue_payload_type => 'SYS.AQ$_JMS_MESSAGE',
    multiple_consumers => true);
END;
/
EXEC DBMS_AQADM.CREATE_QUEUE(
'theTopic','QT_Topic');
EXEC DBMS_AQADM.ADD_SUBSCRIBER(

'theTopic', sys.aq$_agent('MDSUB', null, null));
EXEC DBMS_AQADM.START_QUEUE ('theTopic');

如果Oracle9iAS Containers for J2EE (OC4J)在数据源和资源适配器方面被正确地配置(如下所示),那么现在你的J2EE应用程序应该能使用Oracle数据库中的theTopic了。

从data-sources.xml:


   
   

From $OC4J_HOME/config/application.xml:


   
   
  
    
    
     
      Oracle JMS 
    
    
  
    
    
  
    
    

   
   

J2EE数据库调优技巧

对任何数据库进行调优的基础知识对J2EE应用程序是有用的。作为一个数据库管理人员,你知道调优的第一步是对SQL语句进行调优。你必须找到和改进会减慢数据库运行速度的不良SQL语句。为了避免全表扫描,你可能必须将更多的索引添加到你的应用程序中。对于CMP bean来说,这可能是一个具有挑战性的任务,因为容器生成SQL语句。在这种情况下,你将必须与开发人员进行合作,用SQL语句构建用于finder/select方法的索引。你可以使用诸如P6spy (www.p6spy.com)之类的一些开放源码工具来获取和记录由你的J2EE容器的CMP引擎所生成的实际SQL语句。

因为使用EJB的大部分应用程序实际上是在线事务处理(OLTP),所以在开发人员使用EJB时,你可以使用常规的数据库调优知识来调优你的数据库。作为一个数据库管理员,你知道很好地了解数据库SQL处理引擎对编写最优化的SQL语句是必需的。在昂贵的事务处理系统中尤为如此。一般来说,由OLTP应用程序所发布的SQL命令每次执行相关的几行。如果一个索引能够指向你希望的确切行,那么你的Oracle数据库则可以制定一个准确的计划来通过尽可能短的路径来有效地访问那些行。当你有一个事务性应用程序时,对重做日志进行调优也是非常重要的。像使用任何Oracle数据库应用程序一样,你可以使用Oracle StatsPack实用程序来收集数据库和会话级的性能信息,以便对你的数据库进行调优,使其能够最好地执行EJB应用程序。要获取数据库调优的更多详细信息,请参看《Oracle9i性能调优指南和参考》(Oracle9i Performance Tuning Guide and Reference,可从 otn.oracle.com/documentation上获得)一文。

持久性,最大的挑战

很显然,对于构建J2EE应用程序的机构来说,使数据持久是到目前为止最大的挑战之一。J2EE应用程序开发人员有几个持久性选项:他们可以使用JDBC将持久性逻辑编写到他们的应用程序代码中构建CMP bean,或者使用诸如Oracle9iAS TopLink之类的持久性层。自己构建解决方案在维护方面的成本极为高昂。

将Oracle9iAS TopLink置入Oracle9iAS中已经有很多年了,它几乎能够处理持久性方面的任何情况。TopLink提供一个持久性基础架构,使开发人员能够将来自多种体系结构的数据(包括EJB(CMP和BMP)、常规的Java对象、servlet、JSP、会话bean和消息驱动bean)集成在一起。TopLink允许Java应用程序访问作为对象存储在关系数据库中的数据,从而极大地提高了开发人员的工作效率。TopLink还具有通过最大限度地降低数据库命中率和网络流量及利用由JDBC和数据库提供的最优化来提升应用程序性能的特性。TopLink是通过创建一个元数据"描述符"(映射)集来实现上述特性的,这些元数据描述符定义了以一个特定的数据库模式存储对象的方式。TopLink在运行时使用这些映射动态地生成所需的SQL语句。这些元数据描述符(映射)独立于语言和数据库,开发人员能够在无需对它们所表示的类进行重编译的情况下修改它们。欲了解使用TopLink的更多相关内容,请参见。

更多的3-字母缩写

我的一个数据库管理员朋友告诉我,在一次会议中当开发人员告诉应用服务器管理员"如果你不喜欢使用WAR,你可以从SCS获取我的EAR"时,他感到非常困惑。让我来解释一下:WAR(Web Application aRchive,Web应用程序归档)文件是一个打包Web应用程序的标准方式,而EAR(Enterprise Application aRchive,企业应用程序归档)是能够部署到符合J2EE规范的应用服务器的归档文件。(一个EAR 可能包括一个WAR或EJB-JAR。 SCS代表Source Control System(源码控制系统))。但是学习J2EE术语只是第一步。如果在Oracle上运行良好的、符合ANSI SQL 92的简单SQL语句不能运行在声称符合ANSI SQL的其他数据库上,那么你如何能够期望为Weblogic构建的复杂商务应用程序与Oracle协同工作?这就是太阳微系统公司开发兼容性测试套件(Compatibility Test Suite)的原因,该套件是千条测试的一个集合,每个应用服务器都必须通过这些测试来宣称自己是符合J2EE或经过J2EE认证的。

弥补通信差异

J2EE开发人员和数据库管理员说不同的语言。开发人员在对象和bean方面进行考虑--意欲使他们的代码永远不受数据库的影响或限制。另外,开发人员总是希望从数据库获取最快的性能。而作为一个数据库管理员,你是机构的信息守护者:你希望遵循数据库规则,不愿意改变数据库模式。到现在为止,你应该已经对J2EE有了足够的了解,能够聪明地与你机构中的Java开发人员进行谈话。通过按照我上面所概述的步骤进行工作,你将能够与Java开发人员协同工作来提高你机构中J2EE数据库应用程序的性能和可靠性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值