1. Trang chủ
  2. » Công Nghệ Thông Tin

Teach Yourself J2EE in 21 Days phần 4 ppt

111 343 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 111
Dung lượng 1,04 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

However, it may be that the physical schema of the persistent data store especially ifthat persistent data store is an RDBMS does not correspond exactly with the logicalschema of the Ent

Trang 1

and the entityelement defined as

<!ELEMENT entity (description?, display-name?, small-icon?, large-icon?, ejb-name, home?, remote?, local-home?, local?, ejb-class,

persistence-type, prim-key-class, reentrant, cmp-version?, abstract-schema-name?, cmp-field*, primkey-field?,

env-entry*, ejb-ref*, ejb-local-ref*, security-role-ref*, security-identity?, resource-ref*,

resource-env-ref*, query*)>

Looking first at theentityelement, much of it will be unchanged What needs to bespecified for a CMP entity are

• cmp-version Always set to 2.0 The value 1.1is supported only for legacy CMPEntity beans written to the EJB 1.1 specification

• abstract-schema-name Any unique name, this defines the name used to identifythe bean in EJB QL queries It makes sense to base this on the name of the bean

In the case study, the JobBeanbean has a schema with the name of Job

• cmp-field One for each cmp-field(but not cmr-fields) In the Jobbean, thecmp-fields are ref, customer, and description The locationand skillsfieldsare cmr-fields representing relations to the Locationand Skillbeans respective-

ly, and so do not appear

• primkey-field This optional field is used when the primkey-classelementdoes not identify a custom primary key class It is not specified for the Jobbean,but for the Locationbean, for example, it is specified and is set to name

• query Defines an EJB QL query, associating it with a finder or select method.Listing 7.12 shows the entityelement for the Jobbean

LISTING 7.12 Job Bean’s entity Element

Trang 2

31: <! shouldn’t be needed, but

➥ctx.getEJBHome() returns null in J2EE RI >

53: WHERE j.customer = ?1</ejb-ql>

54: </query>

Trang 3

65: WHERE o.location.name = ?1</ejb-ql>

66: </query>

67: </entity>

The definition of the queryelement is as follows:

<!ELEMENT query (description?, query-method, result-type-mapping?, ejb-ql)>You can see from the listing that the query-methodelement just identifies the name ofthe finder or select method Note that if a finder method is being identified, it is the nameappearing in the local-home (or home) interface; that is, without the ejbprefix On theother hand, if a select method is being identified, there will be an ejbprefix, becauseselect methods never appear in the interfaces of the bean

The result-type-mappingelement applies only if the method identified by methodhas identified a select method, and only then if the EJB QL string returns Entitybean references (that is, if the SELECT [DISTINCT] OBJECT(x)style of select_clausehas been used) The allowable values are Localand Remote, indicating whether theclause should return references through the local or remote interfaces Obviously, if spec-ified, the bean must provide an interface of the appropriate type; if not specified, thebean must provide a local interface, because this is the implied value for the result-type-mappingelement

query-Of course, all of this deployment information can be entered graphically using thedeploytool Figure 7.8 shows some of the equivalent information for Listing 7.12.

deploytool lets CMP deployment informa- tion be defined through

a GUI.

Trang 4

The relationships Element

The relationshipselement is defined in the EJB 2.0 DTD as follows:

<!ELEMENT relationships (description?, ejb-relation+)>

That is, it consists of one or more ejb-relationelements These in turn are defined as

<!ELEMENT ejb-relation (description?, ejb-relation-name?, ejb-relationship-role, ejb-relationship-role)>

which is a somewhat curious definition: an optional description, an optional name, andthen precisely two ejb-relationship-roleelements Each of these identifies the rolethat some bean is playing with respect to the relationship

It is possible that the same bean appears in both roles to model recursive relationships.

Note

The ejb-relationship-roleelement is defined as follows:

<!ELEMENT ejb-relationship-role (description?, ejb-relationship-role-name?, multiplicity, cascade-delete?, relationship-role-source, cmr-field?)>

with

<!ELEMENT relationship-role-source (description?, ejb-name)>

You can see that the relationship-role-sourceelement merely identifies an Entitybean by name This element’s name is perhaps somewhat misleading, because it is nei-ther a “source” nor (for that matter) a target within the relationship The navigability ofthe relationship comes from the presence (or not) of the cmr-fieldelement Of course,

at least one of the ejb-relationship-roleelements must have a cmr-fieldspecified,and if both do, the relationship is bi-directional

The choices for the multiplicityelement are either Oneor Many There will be two suchelements in the complete ejb-relationelement, so this is what gives one-to-one, one-to-many, many-to-one, or many-to-many

There is also an optional cascade-deleteelement Perhaps non-intuitively, this is placed

on the “child” (multiplicity = many) side of a relationship

Finally, the cmr-fieldis defined as follows:

<!ELEMENT cmr-field (description?, cmr-field-name, cmr-field-type?)>

Trang 5

The cmr-field-nameelement just names the cmr-field(for example,skillsor tionfor the Jobbean) The cmr-field-typeelement is needed only for multi-valuedcmr-fields (for example, skillsfor the Jobbean) and indicates whether the return type

loca-is a java.util.Collectionor java.util.Set

Do not confuse this return type with the allowable return types for select methods These are unrelated areas that just happen to have the same allowable return types.

Trang 6

description location Location.name(FK)

name

Skill

description requires

jobs jobs

location location for

Trang 7

Location

description

customer ref

Job

description location Location.name(FK)

name

Skill

description requires

jobs jobs

location location for

edit-To actually deploy the enterprise application, use the buildAlland deploybatch scripts

in the day07\builddirectory, or use buildAllto assemble the enterprise application and

deployfrom deploytool

Trang 8

should be used only for deploying enterprise applications and for configuring J2EE RIservers.

On the other hand, in the development environment, it can be an error-prone task toattempt to write XML deployment descriptors from scratch If a valid deploymentdescriptor already exists, modifying it (to add a new ejb-refelement or something simi-lar) can often be accomplished, but larger changes (such as adding a completely newbean) will be more difficult without much practice Here,deploytoolcomes into its own

to modify the enterprise application as required (or indeed, to create an enterprise cation from scratch)

appli-When you are happy that the beans and clients in your enterprise application are

correct-ly configured,deploytoolallows the XML deployment descriptor to be saved, forchecking into source code control This is shown in Figure 7.12

deploytool can be

used to configure

rela-tionships through its

Trang 9

The Tools, Descriptor Viewer menu option brings up a dialog box displaying the XMLdeployment descriptor; from there, the data can be saved as a file This menu option iscontext sensitive, so what it shows will depend on the node selected in the explorer onthe left pane in the GUI The descriptor viewer dialog should be brought up for eachnode under the enterprise application node, and for the enterprise application node itself.

In the case study, this means for each of the clients, for the dataEntity EJBs, for theagencySession EJBs, and for the agencyapplication node

Deploying a CMP Entity Bean

The enterprise application can be deployed either from the command line (deployscript

in the build directory) or using deploytoolitself

However, before an enterprise application containing CMP Entity beans can be deployed,the default SQL must be generated by using the Deployment Settingsdialog box This

is performed once for each CMP Entity bean, as shown in Figure 7.13

deploytool allows SQL to create the database schema to be generated.

You can see from the figure that J2EE RI generates default SQL It allows the SQL queryfor the finder and select methods to be tuned, and also (the container methodsradiobutton) allows the actual SQL to create the tables, insert rows, and so on to be modified

also The case study does not change any of this default SQL.

Right at the beginning of today’s chapter, it was noted that the schema of the database for the case study had changed from that of Day 6 If one want-

ed to use the exact schema from Day 6, it could have been entered here.Note

Trang 10

Also, the dialog allows the underlying tables to be created and deleted on ploy This obviously isn’t appropriate for a production environment, because it woulddelete any data already there It also is not appropriate for the case study, because there isexample data

cre-ates exactly the same schema as that generated by default by J2EE RI It also populates that schema with the same data as in Day 6 and creates views for backwards compatibility.

Note

You will recall that the auxiliary deployment descriptor agency_ea-sun-j2ee-ri.xml

contains all the mappings of the logical dependencies of the EJBs to the physical runtimeenvironment This includes all of the SQL specified in Figure 7.13

It was noted earlier that when creating a new CMP Entity bean, it is often easiest to loadthe enterprise application into deploytooland then save the XML deployment descriptorusing the Tools, Descriptor Viewer menu option/dialog Unfortunately,deploytooldoesnot provide any easy way to write out the auxiliary deployment descriptor, and it isrequired for the command line approach The buildAllscript calls the addJ2eeRiToEar

script that does precisely this

The only real option is to save the agency.earfile once modified, and then use a tool,such as WinZip, to load up the EAR file The auxiliary deployment descriptor can beextracted from that

Patterns and Idioms

This section presents some patterns and idioms that relate to CMP Entity beans You’llrecognize some of the points made here; they were made earlier in the “ContainerManaged Relationships” section

Normalize/Denormalize Data in ejbLoad()/ejbStore()

Under CMP, theejbLoad()and ejbStore()methods don’t have very much (or indeedanything) to do; the interactions with the persistent data store are done by the EJB con-tainer

However, it may be that the physical schema of the persistent data store (especially ifthat persistent data store is an RDBMS) does not correspond exactly with the logicalschema of the Entity bean

Trang 11

For example, the Applicanttable defines two columns—address1and address2.However, at least conceptually, the ApplicantEntity bean has a vector field of address,

of type String[]; there could be many lines in the address(and it’s just that the cal schema of the persistent data store constrains the size of this vector to 2):

physi-Santa Claus

No 1 Grotto Square (line 1) Christmas Town (line 2) North Pole (line 3) The World (line 4) Earth (line 5) The Solar System (line 6, and so on …)Because the ejbLoad()method is called after the EJB container has loaded the data, itmay renormalize the data In other words, the data in the two cmp-fields of address1and address2can be converted into the String[] addressfield The bean’s clients’ view(as presented by the methods of the local interface) is that the addressfield is a vector.Conversely, the ejbStore()method, called just before the EJB container updates thedata, can denormalize the data In other words, the data in the addressvector field can

be “posted” back to the address1and address2 cmp-fields

Although the EJB specification allows cmp-fields to be exposed in the local (or remote)interface of a CMP Entity bean, there are problems with doing so Because the settermethod that corresponds to the field is generated by the EJB container, it is not possible

to perform any application-level validation

Instead, it is better to create a shadow setter method, have it do any validation, and thendelegate to the actual cmp-fieldsetter method

You may also want to create a shadow getter method This would allow you symmetry inthe names of the methods, and you could also perhaps do some caching of values orother application-level logic

As an example, instead of exposing the getter and setter methods for the descriptioncmp-fieldof the Jobbean, you might have a local interface of

package data;

import javax.ejb.*;

// imports omitted public interface JobLocal extends EJBLocalObject { String getDescriptionField();

void setDescriptionField(String description);

Trang 12

// code omitted }

with a corresponding implementation of

} public abstract String getDescription();

public abstract void setDescription(String description);

}

Don’t Expose cmr-fields

Although the EJB specification allows cmr-fields to be exposed in the local interface of

a CMP Entity bean, it may be best not to There are two reasons why exposing the fieldcauses problems, both related to the returned collection from the getter method of

cmr-a cmr-field:

• The first is that this returned collection is mutable A client can change of theEntity bean’s relationships with other beans by manipulating this collection Inother words, the bean’s state is changed without it being aware

• The second is that the returned collection becomes invalid when the transactioncontext changes This is actually good that this is so, but it is a subtle point, andsome developers might not appreciate it if less than familiar with EJB transactions(making debugging their application somewhat tricky)

An alternative to exposing the setter method of a cmr-fieldwould be for the bean tooffer alternative methods, such as addXxx()and removeXxx(), on the bean itself andhave these call the setter method An alternative to exposing the getter method would be

to expose a shadow method called something like getXxxCopy() This would create acopy of the collection The method name suggests to the client that they will not be able

to change the relationships of the bean Indeed, the returned collection could even bemade immutable

Trang 13

As an example, instead of exposing the getter and setter methods for the skills cmp-fieldof the Jobbean, you might have a local interface of

package data;

import javax.ejb.*;

import java.util.*;

// imports omitted public interface JobLocal extends EJBLocalObject { Collection getSkillsCopy();

void addSkill(SkillLocal skill);

void removeSkill(SkillLocal skill);

// code omitted }

with a corresponding implementation ofpackage data;

import javax.ejb.*;

import java.util.*;

// imports omitted public abstract class JobBean implements EntityBean { public Collection getSkillsCopy() {

List skills = new ArrayList();

for(Iterator iter = getSkills().iterator(); iter.hasNext(); ) { skills.add(iter.next());

} return Collections.unmodifiableList(skills);

} public void addSkill(SkillLocal skill) { getSkills().add(skill);

} public void removeSkill(SkillLocal skill) { getSkills().remove(skill);

} public abstract Collection getSkills();

public abstract void setSkills(Collection skills);

// code omitted }

Enforce Referential Integrity Through the Bean’s Interface

Entity beans represent the domain layer in the n-tier architecture, and Entity beans have tionships among themselves If a method in a bean’s interface has an argument of some bean(usually for a relationship), this bean should be defined via the local reference rather than byits primary key In other words, referential integrity is effectively enforced; the client guaran-tees that the bean exists, because it passes through an actual reference to that bean

Trang 14

This idiom is honored implicitly for CMP Entity beans that expose their cmr-fields ForCMP Entity beans that provide shadow methods (as discussed earlier), these shadowmethods should still deal with local references to the related beans, rather than identify-ing the related bean by its primary key

This idiom applies equally to BMP Entity beans Indeed, if BMP Entity beans are written to follow this idiom, it becomes that much easier to convert them to CMP.

Note

Use Select Methods to Implement Home Methods

Select methods can only be called by a bean itself, so they act as helper methods A mon place where they are often used is in implementing home methods

com-For example, the Jobbean could have provided a home interface to count the number ofjobs advertised This could have been implemented as follows:

with a corresponding implementation of

} public abstract Collection ejbSelectAllJobs();

// code omitted }

Trang 15

The ejbSelectAllJobs()EJB QL query string would be simplySELECT OBJECT(j)

FROM Jobs AS j

EJB QL does not (yet) support a SELECT COUNT(*) syntax, so this is the only way of performing counts (other than resorting to direct access to the data store).

Note

Gotchas

The following is a quick checklist of “gotchas” to help you with your implementation:

• If the primary key is composite, a custom primary key class must be defined Thefields of this class must be publicand must correspond in name and type to cmp- fields of the bean class

• cmp-fieldand cmr-fieldfields must begin with a lowercase letter, (so that it can

be capitalized in the corresponding getter and setter method names)

• If a collection is returned from a cmr-field’s getter method, it must not be fied other than through Iterator.remove() (see EJB specification, section10.3.6.1)

modi-• Collections returned by getter methods cannot be used outside of the transactioncontext in which they were materialized

• If a bean has no relationships, the Collectionreturned by the cmr-field’s gettermethod will be empty, it will not be null Conversely, if calling a cmr-field’s set-ter method,nullcannot be used; instead an empty collection (such as

Collections.EMPTY_LIST) must be passed in

• EJB QL strings are in single quotes!!!

• EJB QL strings define placeholders as ?1,?2, and so on (rather than the JDBC tax of just ?) This allows the arguments of the corresponding finder or selectmethod to be bound in more than once

syn-• When comparing strings in EJB QL, the strings must be identical to be equal (This

is different from SQL where trailing whitespace is usually ignored.)

• An EJB QL empty string is ‘’(0 characters) Some RDBMS treat this as a null

string, so beware! (See EJB Specification, section 11.2.9.)

Trang 16

Summary

Well done! In three days (Days 5, 6, and 7), you’ve covered pretty much everything youneed to know about writing EJBs There’s a little mopping up of relatively minor issuestomorrow, but you now well and truly have the essentials under your belt

Today you saw how the n-tier architecture is subtly revised again, with the responsibilityfor persistence delegated downwards (into subclasses) to the EJB container-generatedsubclasses of the CMP Entity bean You also learned that the lifecycle for CMP Entitybeans is substantially the same as BMP Entity beans and, in general, there is less coding

to be done in the lifecycle methods (ejbCreate(),ejbLoad(),ejbStore(), and

ejbRemove())

You now know that cmp-fields are defined in the deployment descriptor and correspond

to primitive and to Serializableobjects They are represented in the CMP bean class asabstract getter and setter methods You also know that cmr-fields work very much thesame way but deal with references to the local interfaces of other Entity beans (or collec-tions thereof) This is what makes local interfaces the basis of container-managed rela-tionships

Finally, you saw how to construct EJB QL queries and how to relate them to both findermethods and to the helper select methods

Q&A

Q What does CMP stand for?

A CMP stands for Container Managed Persistence.

bean’s interfaces?

A cmp-fieldmethods can appear in any interface; cmr-fieldmethods can appearonly in local interfaces

Q What keywords or features of ANSI SQL does EJB QL not (yet) support?

group by, order by (among others)

Q How are the parameters of a select method defined?

class itself

Trang 17

Q How is navigability defined in the deployment descriptor?

A The presence of the cmr-fieldelement indicates navigability

Exercises

The job agency case study defines a complete set of Session beans, and Entity beans All

of the Entity beans except the Applicantbean are implemented using CMP; theApplicantbean has been implemented using BMP The exercise is to implement anApplicantEntity bean to use CMP The source code and deployment descriptors can befound under day07\exercise, and the directory structure is the same as yesterday

In more detail, the fields of the Applicantbean need to be converted into either fields or cmr-fields:

cmp-• login This is the primary key for the ApplicantEntity bean and will be a field.

You should find that the JobCMP Entity bean acts as a good model for your new version

of the Applicantbean One difference is in the primary key The Jobbean required aJobPKbecause it had a composite primary key For your Applicantbean, there is no cus-tom primary key, so you will need to nominate the login cmp-fieldas its primary keyusing the primkey-fieldelement in the deployment descriptor Another related differ-ence is that the Jobbean has to deal with ensuring that its customer cmp-fieldis a valididentifier for a Customer Your Applicantbean will not have this complication

There should be no need to change the Agencyand RegisterSession beans that call theApplicantbean, because it is only the internal implementation that is changing, not theinterfaces

The steps you should perform are as follows:

1 If you didn’t do so earlier today, convert the Agencydatabase to its CMP version.The steps to do this were described in the “A Quick Word about the Case StudyDatabase” section

Trang 18

2 Re-acquaint yourself with the ApplicantLocalHomeand ApplicantLocalfaces However, these will not need to be changed

inter-3 Update the ApplicantBeanclass; base this on JobBean

4 The CMR relationships that will be built will be bi-directional This is neededbecause, otherwise, the code generated by the J2EE RI fails to compile So, in each

of LocationBeanand SkillBean, uncomment the getApplicants()and

setApplicants()methods Note that these have not been exposed in the respectiveinterfaces

5 Build the enterprise application (agency.earin the jardirectory) and then load itinto deploytool Delete the Applicantbean from the enterprise application, andthen add it in again into the data_entity_ejbs ejb-jar As you add it, you canspecify that it is a CMP bean

6 Specify the appropriate cmp-fields for the new bean

7 Add a many-to-many relationship from Applicantto Skill Make the relationshipbi-directional

8 Add a many-to-one relationship from Applicantto Location Make the ship bi-directional

relation-9 Use the deploytool’s Descriptor Viewer dialog to save the XML deploymentdescriptor

10 Now deploy the enterprise application (from the deploytoolGUI), providing thenecessary auxiliary deployment information in the wizard that is displayed Testyour program by using the AllClientsclient, run with run\runAll

11 Optionally, use WinZip or equivalent to extract the auxiliary deployment descriptorand save as dd\agency_ea-sun-j2ee-ri.xmlfrom the agency.earfile previouslygenerated Then re-build and deploy using build\buildAlland build\deploy.Good luck A working example can be found in day07\agency

Trang 20

Developing J2EE Applications

8 Transactions and Persistence

9 Java Messaging Service

Trang 22

You spent Day 6 and Day 7, “CMP and EJB QL,” comparing the two different tence approaches offered by EJB in the guise of BMP and CMP Entity beans The BMPEntity beans were implemented using JDBC, but that is only one of a number of tech-nologies offered by J2EE and Java in general Today, you will learn

persis-• How to manage transactions explicitly in EJBs

• How transactions are managed “behind the scenes” in an EJB environment

• Some other persistence technologies other than JDBC—specifically, SQLj andJDO

Overview of Transactions

If you’ve used RDBMS before, or completed a Computer Studies course or read anyother J2EE book, you’ve probably read a section like this one already But read on any-way, if only to be acquainted with some of the J2EE terminology that is used in thisarena

A transaction is an atomic unit of work:

• Atomic unit means indivisible—either every step within the transaction completes

or none of them do

• Work here usually means some modification to data within a persistent data store.

In RDBMS terms, this means one or more INSERT,UPDATE, or DELETEs However,strictly speaking, it also applies to reading of data through SELECTstatements.For a persistent data store to support transactions, it must pass the so-called “ACID” test:

• Atomic—The transaction is indivisible; the data store must ensure this is true.

• Consistent—The data store goes from one consistent point to another Before the

transaction, the data store is consistent; afterwards, it is still consistent

The age-old example is of transferring money between bank accounts This willinvolve two UPDATEs, one decrementing the balance of account #1 and the otherincrementing the balance of account #2 If only one UPDATEoccurs, the transaction

is not atomic, and the data store is no longer in a consistent state

• Isolation—The data store gives the illusion that the transaction is being performed

in isolation Enterprise applications have many concurrent users who are all forming transactions at the same time, so behind the scenes, the data store uses tech-niques, such as locks, to serialize access to the contended data where necessary

per-• Durability—If a transaction completes, any changes made to the data as a result of

that transaction must be durable In other words, if the power were to fail a lisecond after the transaction has completed, the change must still be there whenpower is reconnected

Trang 23

Many data stores use transaction logs to address this requirement The transactionlog holds a journal of changes made to the actual data When the transaction com-pletes, the log is written to disk, although the actual data need not be

If you are a Windows user, you may know that Windows NT, 2000 and XP support a filesystem type called NTFS This replaces the FAT and FAT32 filesystem types used in Windows 95, 98, and ME.

Microsoft often say that NTFS is more reliable, although slightly slower than FAT/FAT32 This is because NTFS has a built-in transaction log, whereas FAT/FAT32 does not.

Note

Many data stores allow transactions to be started explicitly using a syntax such as thefollowing:

begin transaction t1

where t1is the (optional) name transaction Transactions are completed using either

commit(make changes permanent) or rollback(undo all changes made in the tion, and revert all data back to the state before the transaction began) Many data storeswill use

transac-commit transaction t1

and

rollback transaction t1

Some data stores support the concept of nested transactions, whereby (for a

single user) one transaction can be started while another transaction is still

in progress In other words, two begin transaction s can be submitted out a commit or rollback between them.

with-However, the EJB specification and many others support only flat

transac-tions, whereby one transaction must be completed before another is begun

(see EJB specification, section 17.1.2) Consequently, nested transactions are not considered further.

Note

To conclude this short introduction, consider the fragment of SQL shown in Listing 8.1

It transfers $50 from account #20457 to account #19834

Trang 24

LISTING 8.1 Example Fragment of SQL to Transfer Money Between Accounts

1: begin transaction transfer_money 2:

3: update account 4: set balance = balance - 50 5: where account_id = 20457 6:

7: update account 8: set balance = balance + 50 9: where account_id = 19834 10:

11: commit transaction transfer_money

In effect, there are two different types of commands:

• Lines 1 and 11 demarcate the transaction

• Lines 3–5 and 7–9 modify data

A conventional RDBMS processes all of the SQL in Listing 8.1, but it is performing twodifferent roles in doing so To understand and process the transaction demarcation com-

mands, it is acting as a transaction manager To understand and process the remaining lines, it is acting as a resource manager.

In the EJB specification, these two responsibilities are split In principle, you can think

of the EJB container as acting as the transaction manager, and the persistent data store

acting only as the resource manager The term transaction coordinator is sometimes used

instead of transaction manager because there could be more than one resource whosetransactions are being coordinated

Splitting the responsibilities of transaction management and resource management hastwo consequences For the bean provider, it means that to start a transaction, the beanmust interact both with the EJB container and with the persistent data store The formerinteraction is largely implicit because it is configured through the deployment descriptor(and as you know, the latter interaction is implicit if CMP Entity beans are used) Theother consequence is that, for the persistent data store, it must defer all transaction con-trol responsibility up to the EJB container Behind the scenes, there is some quite sophis-ticated communication going on; you’ll learn a little about this activity later on today

Container-Managed Transaction Demarcation

You’ve spent the last three days writing and deploying EJBs without really having toworry too much about transactions This isn’t to say that there have been no transactions

in use; far from it Every interaction with the database performed in the case study has

Trang 25

involved transactions However, the Session and Entity beans deployed have used

con-tainer manager transaction demarcation (here referred to as CMTD, though the

abbrevi-ation isn’t used in the EJB specificabbrevi-ation) Informabbrevi-ation in the deployment descriptor cates when the EJB container should start and commit transactions

indi-Figure 8.1 shows a diagram that you saw first on Day 6

local client

home

remote

local home

local

location transparency

security and transactions

home stub

remote stub

This shows how the EJB proxy objects (those implementing the javax.ejb.EJBObject

or javax.ejb.EJBLocalObjectinterfaces) implement the transaction semantics This isone of the reasons that a bean must never implement its own remote interface To do sowould mean that it could unwittingly return a reference to itself as a Remoteinterface,subverting any security and transaction checks performed by its proxy

Listing 8.2 shows a fragment of the deployment descriptor for the AdvertiseJobSessionbean from Day 7

10: </enterprise-beans>

11: <assembly-descriptor>

12: <container-transaction>

Trang 26

22: </method>

23: <trans-attribute>Required</trans-attribute>

24: </container-transaction>

25: … lines omitted … 26: </assembly-descriptor>

27: </ejb-jar>

As you have seen over the last three days, the enterprise-beanselement consists ofsessionor entityelements The session element has a transaction-type element which,under CMTD, should have the value of Container For entity elements, the transaction-type is not specified because entity beans must always be deployed using CMTD, so it isimplicit

Each method of the remote interface must be present in a container-transactionment The same is true of the methods in the home interface The relevant DTD defini-tions that govern the structure of the deployment descriptor are as follows:

ele-<!ELEMENT ejb-jar (description?, display-name?, small-icon?, large-icon?, enterprise-beans, relationships?, assembly-descriptor?, ejb-client-jar?)>The assembly-descriptorelement is defined as follows:

<!ELEMENT assembly-descriptor (security-role*, method-permission*,

➥container-transaction*, exclude-list?)>

You can see here that assembly-descriptorelement is all about providing the tion used to create the EJB proxy objects The security-role,method-permission, and exclude-listelements are security related, and the container-transactionelementobviously defines transaction-related information

informa-The security-related elements of the assembly-descriptorelement are not consideredfurther here However, the container-transactionelement is relevant to the discussion

It is defined in the DTD as follows:

<!ELEMENT container-transaction (description?, method+, trans-attribute)>and the methodelement is defined as

<!ELEMENT method (description?, ejb-name, method-intf?,

➥method-name, method-params?)>

Trang 27

So, a container-transactionelement identifies one or more methods The methodment identifies a method in the home or remote interface; the method-intfelement isonly needed in those rare occasions when there happens to be a method of the samename in both the home and remote interfaces The method-namemust be specified,although the value of *can be used as a convenient shortcut to indicate all methods The

ele-method-paramselement is optional and is used to distinguish between overloaded sions of the same method name If not specified, the methodelement identifies all over-loaded versions of the method with the specified name

ver-Finally, the bit that really matters The trans-attributeelement indicates the

transaction-al characteristics to be enforced when the specified method is invoked A transaction may

or may not be in progress; in the terminology of the EJB specification, there may or may

not be a current valid transactional context When a method is invoked, the EJB container

needs to know what should occur For example, if there is no transaction in progress, is oneneeded to execute the method? Should a transaction be started automatically if there isn’t

one? Perhaps a transaction can be started even if another one is in progress? And so on.

There are six possible values; their semantics are shown in Table 8.1

T ABLE 8.1 Different CMTD Semantics Are Indicated by the trans-attribute Element

does not support an external transaction not specify the transactional coordinator Any current transaction context semantics of the method.

will be suspended for the duration of the method.

current transaction context will be used

if present; otherwise, one will be created.

like Required ) Otherwise, use unspecified NotSupported This makes transaction context (acts like NotSupported ) the Supports a highly dubi-

ous choice The method must guarantee to work in the same way whether or not there is a transaction context available.

existing valid transaction context will be example, for a bean that suspended for the duration of the method generates unique IDs or for

a bean that writes to a log).

Trang 28

Mandatory A valid transaction context must exist; an Useful for helper beans’

exception will be thrown by the EJB container methods, designed to be otherwise The transaction context will be used called only from another

bean.

Never There must be no current transaction context Acts as NotSupported.

An exception will be thrown by the EJB container otherwise The method invokes with

an unspecified transaction context.

For Entity beans, only the Required,RequiresNew, and Mandatory trans-attributeues are recommended The problem with NotSupported,Never, and (if invoked with nocurrent transaction context) Supportsis that, in addition to performing the businessmethod, the EJB container must also perform the ejbLoad()and ejbStore()methods.These will be performed with the same transactional context as the business method,

val-which is to say, with no transactional context What might happen then is somewhat

unde-fined, as the EJB specification is at pains to point out Indeed, it goes so far as to list (insection 17.6.5) four or five different ways in which the EJB container might decide to act

T ABLE 8.1 Continued trans-

Never use NotSupported, Never, or Supports as trans-attribute ues with Entity beans.

val-Caution

As usual, the deploytoolGUI can also be used to configure the information within thedeployment descriptor, as shown in Figure 8.2

You are likely to find that the vast majority of your beans’ methods will use the

Required trans-attributevalue Indeed, this is the value that has been used in the casestudy over previous days

Although CMTD means that the EJB container automatically starts, suspends, and pletes transactions, this is not to say that the beans themselves cannot influence the trans-actions After all, if an Entity bean hits an error condition that means that the transactionshould be aborted, it needs some way to indicate this to the EJB container As an exam-ple, consider the hackneyed example of withdrawing money from a bank account If thebalance would go into the red, (or perhaps more likely, beyond an overdraft limit), theEntity bean that represents the account would want to indicate that the transaction should

com-be aborted

Trang 29

To do this, the bean can use two transaction-related methods provided by itsEJBContext

In the case of a Session bean, this will be the javax.ejb.SessionContextpassed inthrough the setSessionContext()method, and for an Entity bean, this will be the

javax.ejb.EntityContextpassed in through setEntityContext() To remind you,Figure 8.3 shows a UML class diagram illustrating the methods provided by these inter-faces

back to the different EJB roles you learned about back on Day 2, “The J2EE Platform and Roles.” The intention is that the bean provider completes just the information in the enterprise-beans element, while the application assembler completes the information under the assembly-descriptor This allows an EJB component to be used in different applications, with different transaction and security requirements.

In contrast, the deploytool does not differentiate between the two roles;

the transaction (and security) information are just two of the seven tabs on the right side of the GUI, providing information about the selected EJB; the other five tabs pertain to information found under the enterprise-beans

element.

Note

Trang 30

To cause the transaction to be aborted, the CMTD bean can call setRollbackOnly().This instructs the EJB container to prevent the transaction from being committed Thebean cannot rollback the transaction directly, because the transaction itself is “owned” bythe EJB container, not the bean The getRollbackOnly()method obviously just indi-cates whether the transaction has been marked for rollback.

There is one other transaction-related method in EJBContext, namelygetUserTransaction() However, this cannot be called by a CMTD bean, and anyattempt to do so will result in the EJB container throwing a

java.lang.IllegalStateException.

The EJBContext vides access to the cur- rent transaction.

pro-interface

EJBContext

+getEJBHome():EJBHome +getEJBLocalHome():EJBLocalHome +getEnvironment():Properties +getCallerIdentity():Identity +getCallerPrincipal():Principal +IsCallerInRole(Identity:Identity):boolean +IsCallerInRole(s:String):boolean +getUserTransaction():UserTransaction +setRollbackOnly():void

+getRollbackOnly():boolean

interface

EntityContext

+getEJBLocalObject():EJBLocalO +getEJBObject():EJBObject +getPrimaryKey():Object +setEJBLocalObject(pO:EJBObje

interface

SessionContext

+getEJBLocalObject():EJBLocalO +getEJBObject():EJBObject

interface

javax.transaction.UserTransaction

+begin():void +commit():void +getStatus():int +rollback():void +setRollbackOnly():void +setTransactionTimeout(:int):void !

interface

javax.transaction.Status

+STATUS_ACTIVE:int +STATUS_MARKED_ROLLBACK:int +STATUS_PREPARED:int +STATUS_COMMITTED:int +STATUS_ROLLEDBACK:int +STATUS_UNKNOWN:int +STATUS_NO_TRANSACTION:int +STATUS_PREPARING:int +STATUS_COMMITTING:int +STATUS_ROLLING_BACK:int

manag-If your bean does need more fine-grained control over transactions, the bean must bedeployed using bean-managed transaction demarcation This is discussed next

Trang 31

Bean Managed Transaction Demarcation

If an EJB is deployed using bean managed transaction demarcation (here referred to as

BMTD, though this abbreviation isn’t used in the EJB specification itself), the EJB tainer allows the bean to obtain a reference to a javax.transaction.UserTransaction

con-object using the EJBContext You can see this in Figure 8.3

Motivation and Restrictions

An EJB might need to be deployed under BMTD if the conditions on which a transaction

is started depend on some programmatic condition It could be that one method starts thetransaction and another method completes the transaction

However, the cases where BMTD is needed are few and far between Indeed, they are sorare that the EJB specification limits BMTD to Session beans Entity beans can only bedeployed with CMTD This makes sense because Entity beans represent persistent trans-actional data; the transaction context should be as deterministic as possible

Moreover, if a stateless Session bean starts a transaction, it must also commit that action before the method completes After all, the stateless Session bean will have nomemory of the client that just invoked its method after that method completes, so onecannot expect that the transaction context is somehow miraculously preserved If youwrite a BMTD stateless Session bean that does not commit its own transaction, the EJB

trans-container will rollback the transaction and throw an exception back to the client

(java.rmi.RemoteExceptionfor remote clients, or javax.ejb.EJBExceptionfor local)

Indeed, even with stateful Session beans, there is a restriction Any current transaction inprogress when the BMTD Session bean is called will be suspended by the EJB container,not propagated to the BMTD bean It is possible that, from the bean’s perspective, there

is a current transaction, but that would refer to any transaction not committed when amethod on that bean was last called

Using the Java Transaction API

When a Session bean is deployed under BMTD, there is an implementation choice as tohow it should manage its transactions If interacting solely with an RDBMS, the Sessionbean can manage the transactions directly through the JDBC API Alternatively, it canuse the Java Transaction API, defined by the classes and interfaces in the javax.trans- actionand the javax.transaction.xapackages The latter is to be preferred, if onlybecause transactional access to Java Messaging Service resources (you’ll be learningmore about these tomorrow and the day after) can only be performed through the JTAAPI Equally, servlets can also use the JTA API

Trang 32

For a Session bean to start a transaction, it should first call the getUserTransaction()method of its SessionContext You’ll recall that this was the method that throws anexception under CMTD, but it is the centerpiece of transaction control under BMTD.Obtaining a UserTransactiondoes not mean that a transaction has been started Rather,

it must be started using the begin()method The transaction can then be completedusing either the commit()or the rollback()method The current status can also beobtained using getStatus() This returns an intwhose meaning is defined by theconstants in the javax.transaction.Statusinterface Some of the most common statusvalues are shown in Table 8.2

TABLE 8.2 Some of the Constants Defined in javax.transaction.Status

STATUS_NO_TRANSACTION No transaction is active tran.begin() to start new

transaction.

STATUS_ACTIVE A transaction is active and can Use resource manager.

tran.rollback() to rollback STATUS_MARKED_ROLLBACK A transaction is active, but has tran.rollback()

been marked for rollback Any attempt to commit it will result

in a javax.transaction.

RollbackException being thrown.

The Java 2 Platform Enterprise Edition Specification, the document that

defines the interoperability of all the technologies that make up the J2EE

plat-form, only discusses transaction interoperability in the context of the JTA API.

If nothing else, the semantics of intermixing JDBC and JTA calls are not exhaustively defined, so this should be avoided to minimize chances of portability problems if moving to a different vendor’s EJB container.

Note

There are more constants in the Status interface than those listed in Table 8.2 Later today, (in the “Transactions: Behind the Scenes” section), you’ll be learning about some of the “under-the-covers” mechanics of transaction management; the full list is presented there.

Note

Listing 8.3 shows a possible implementation for the updateDetails()method of

AdvertiseJobbean using BMTD

Trang 33

7: public class AdvertiseJobBean extends SessionBean { 8: public void updateDetails (String description,

➥String locationName, String[] skillNames) { 9:

10: int initialTranStatus = beginTransactionIfRequired();

11:

12: if (skillNames == null) { 13: skillNames = new String[0];

14: } 15: List skillList;

16: try { 17: skillList = skillHome.lookup(Arrays.asList(skillNames));

18: } catch(FinderException ex) { 19: error(“Invalid skill”, ex, initialTranStatus);

➥ // throws an exception 20: return;

21: } 22:

23: LocationLocal location=null;

24: if (locationName != null) { 25: try {

26: location = locationHome.findByPrimaryKey(locationName);

27: } catch(FinderException ex) { 28: error(“Invalid location”, ex, initialTranStatus);

➥ // throws an exception 29: return;

30: } 31: } 32:

40: private int beginTransactionIfRequired() { 41:

42: UserTransaction tran = this.ctx.getUserTransaction();

43: // start a new transaction if needed, else just use existing.

44: // (simulates trans-attribute of REQUIRED) 45: int initialTranStatus;

Trang 34

46: try { 47: initialTranStatus = tran.getStatus();

48: switch(initialTranStatus) { 49: case Status.STATUS_ACTIVE:

50: // just use 51: break;

52: case Status.STATUS_NO_TRANSACTION:

53: // create 54: try { 55: tran.begin();

56: } catch(NotSupportedException ex) { 57: // shouldn’t happen (only thrown if asking for nested exception 58: // and is not supported by the resource manager; not attempting 59: // to do this here).

60: throw new EJBException(

➥ “Unable to begin transaction”, ex);

61: } 62: break;

63:

64: // code omitted; other Status’ covered later 65:

66: default:

67: throw new EJBException(

68: “Transaction status invalid, status = “ +

➥ statusAsString(initialTranStatus));

69: } 70: } catch(SystemException ex) { 71: throw new EJBException(“Unable to begin transaction”, ex); 72: }

73:

74: return initialTranStatus;

75: } 76:

89: if (tran.getStatus() == Status.STATUS_MARKED_ROLLBACK) { 90: tran.rollback();

Trang 35

91: } else { 92: tran.commit();

93: } 94: } catch(Exception ex) { 95: throw new EJBException(

➥ “Unable to complete transaction”, ex);

96: } 97: } 98: } 99: }

The two helper methods,beginTransactionIfRequired()and

completeTransactionIfRequired(), isolate the actual transaction management code, so

it can be reused across different methods

Deploying a BMTD Bean

Of course, when deploying a bean under BMTD, the deployment descriptor should cate a transaction-typeelement of Bean, and you will not need any container-transaction elements under the application-assemblyelement Figure 8.4 shows

indi-deploytoolfor the AdvertiseJobbean, indicating this fact

Trang 36

Incidentally, if a BMTD Session bean calls getRollbackOnly()or setRollbackOnly()

on its SessionContext, the EJB container will throw ajava.lang.IllegalStateException This is reasonable; if a BMTD has access to the UserTransactionobject, it has no need for these methods Instead, it can call thegetStatus()method of UserTransaction, and explicitly call rollback()if needed

Client-Demarcated Transactions

As well as Session beans managing their own transactions, it is also possible for clients

to initiate the transaction and have it propagate through to the EJBs Here, “client” meanseither an application client written using the Swing GUI (such as you have seen in thecase study), or it could equally refer to a Web-based client implemented using servletsand JSPs

For either of these clients, the EJB architecture requires that a UserTransactioncontextcan be obtained via JNDI, bound under the name of java:comp/UserTransaction Sothe code fragment shown in Listing 8.4 will do the trick

LISTING 8.4 Obtaining a UserTransaction Object from JNDI

1: // assuming:

2: // import javax.naming.*;

3: // import javax.transaction.*;

4: InitialContext ctx = new InitialContext();

5: UserTransaction tran = (UserTransaction)

If that philosophical argument does not appeal, perhaps this might A rogue client could

be coded such that it begins a transaction, interacts with (and therefore ties up) variousresources, such as Entity beans, and then not commit This could seriously impact theperformance of your application

Exceptions Revisited

On Days 5 and 6, you learned the appropriate exceptions for your EJB to throw In summary

Trang 37

However, CMTD beans may decide to mark the current transaction for rollback, meaningthat the “owner” of the transaction (the EJB container or some BMTD bean) will beunable to commit that transaction.

If a BMTD bean hits an error condition, it has a choice Because it “owns” the tion, it can simply do a rollback Alternatively, it might elect to keep the transactionactive

transac-If a system-level exception is thrown by a bean, this does have consequences for any

cur-rent transaction If any bean throws a system exception, the EJB container will mark thecurrent transaction for rollback If that bean happens to be a CMTD bean, and the EJBcontainer started a transaction just before invoking the CMTD method (as a result of a

Requiredor RequiresNew trans-attribute), the EJB container will actually rollbackthat transaction

To summarize,

• An application-level exception may or may not leave the current transaction active;

use getStatus()or getRollbackOnly()to find out

• A system-level exception will either mark the current transaction for rollback oreven do the rollback

One last thing on transactions and exceptions Most of the exceptions in javax.ejb

(CreateException,RemoveException, and so on) are application exceptions Some ofthese, especially with CMP Entity beans, are raised by the EJB container itself Ratherunhappily, the EJB specification does not mandate whether these application exceptionsshould mark any current transaction for rollback (see section 10.5.8) Instead, it just indi-cates that the getStatus()or getRollbackOnly()methods should be used to determinethe status of the current transaction In practical terms, what this means is that differentEJB containers could have different implementations, compromising portability

Trang 38

Extended Stateful Session Bean Lifecycle

Occasionally, there is a need for a stateful Session bean to have visibility as to theprogress of the underlying transaction Specifically, a bean might need to know

• Has the transaction started?

• Is the transaction about to complete?

• Did the transaction complete successfully or was it rolled back?

For example, consider the age-old example of a ShoppingCartbean In its purchase()method, it is likely to modify its internal state Perhaps it holds its contents in ajava.util.Listcalled currentContents On purchase(), it might move the contents

of currentContentsto another java.util.Listcalled recentlyBought

Suppose, then, that the transaction that actually modifies the persistent data store fails tocomplete Maybe the shopper doesn’t have enough limit left on his or her credit card.Because Session beans are not transactional, the ShoppingCartbean needs to know that

it should reset its internal state back to the beginning of the transaction In other words, itneeds to move the contents of the recentlyBoughtlist back over to currentContents.Obviously, there is no issue for stateful Session beans deployed under BMTD, becausethey are the owner of the transaction anyway and know when the tran.begin()andtran.commit()methods will be invoked But for CMTD Session beans, there is an issue.The EJB specification addresses this by extending the lifecycle of the bean If a statefulSession bean implements the javax.ejb.SessionSynchronizationinterface, three addi-tional lifecycle methods are defined and will be called at the appropriate points:

• afterBegin() The transaction has just begun

• beforeCompletion() The transaction is about to be committed

• afterCompletion(boolean) The transaction has completed The booleanment has the value trueto indicate that the transaction was committed, or falsetoindicate that the transaction was rolled back

argu-Figure 8.5 is a reworking of argu-Figure 5.14 that you saw back on Day 5 It shows the ful Session bean’s view of its lifecycle (The client’s view and the actual lifecycle man-aged by the EJB container are unchanged)

Trang 39

There are analogies here also with SQL, where the afterBegin()corresponds to a

SELECT … WITH HOLDLOCKstatement, and beforeCompletion()corresponds to the

interface gives the

stateful Session bean

visibility to the

trans-actions managed under

CMTD.

Bound to client Pooled

Passivated

create/ejbCreate remove/ejbRemove

pool too small/setSessionContext

[too many active]

TX business method

[business method or remove invoked]/ejbActivate

commit/beforeCompletion afterCompletion(true) Ready

Ready in xact

Trang 40

Transactions: Behind the Scenes

The EJB specification starts off by listing nine goals The second of these reads as follows:

“The Enterprise JavaBeans architecture will make it easy to write applications: Application developers will not have to understand low-level transaction and state management details, multi-threading, connection pooling, and other complex low- level APIs.”

The EJB specification (downloadable fromhttp://java.sun.com/products/ejb/index.html) largely succeeds in addressing thisgoal—as a developer, you really do not need much knowledge about how transactionsare managed The fact that this book only covers transactions today is testament to that.Nevertheless, like most technical topics, it can be helpful to have an insight as to what isgoing on “behind the scenes.” But if you want to skip this material and make a shorterday of it, please do so You can always re-read at a later date if you find yourself wanting

to know more

Transaction Managers, Resource Managers, and 2PC

You already know about the terms resource manager and transaction manager (or action coordinator) In most EJB applications, an RDBMS will take the place of aresource manager, and the EJB container itself will be the transaction manager

trans-This division of responsibilities is required because in an EJB architecture, the data used

by Session beans or represented by Entity beans may reside in more than one persistentdata store For example, one Entity bean might map onto an Oracle RDBMS, and anoth-

er Entity bean may map onto a Sybase RDBMS, as shown in Figure 8.6 (The numberswill be explained shortly.)

The J2EE platform separates resources and transaction man- agers.

client

session bean

entity bean entity bean

Ngày đăng: 13/08/2014, 08:21

Nguồn tham khảo

Tài liệu tham khảo Loại Chi tiết
2: import javax.jms.*;3 Khác
4: public class BulletinBoardPublisher { Khác
5: private TopicConnection topicConnection Khác
6: private TopicSession topicSession Khác
7: private TopicPublisher bulletinBoardPublisher Khác
8: private Topic bulletinBoard;9 Khác
16: for (int i = 0; i &lt; 10; i++) { Khác
17: String bulletin = “Bulletin Board Message number: “ + i Khác
18: System.out.println (bulletin) Khác
19: publisher.publishMessage(bulletin); 20: } Khác
21: publisher.close() Khác
22: } catch(Exception ex) { Khác
23: System.err.println(“Exception in BulletinBoardPublisher: “ + ex) Khác
30: topicConnection = topicFactory.createTopicConnection() Khác
31: topicSession = topicConnection.createTopicSession(false, ➥ Session.AUTO_ACKNOWLEDGE) Khác
32: bulletinBoard = (Topic)context.lookup(JNDItopic) Khác
33: bulletinBoardPublisher = ➥ topicSession.createPublisher(bulletinBoard) Khác

TỪ KHÓA LIÊN QUAN