Directory listing of http: uap.unnes.ac.id ebook biblebook Visual Basic 6 com & Library Books
18
C H A P T E R
Using COM +
Transactions
✦
✦
✦
✦
In This Cha pter
I
n this c hapter, I’ll sho w yo u ho w to c reate a COM+ transac tio n. These transac tio ns c an be used to implement an n-tier
applic atio n system, whic h c an o ffer signific ant perfo rmanc e
impro vements when c o mpared with mo re traditio nal c lient/
server applic atio ns.
A Brief Overview of COM +
Writing a COM+ pro gram isn’t diffic ult. If yo u understand ho w
to c reate and use a Class mo dule, then writing a COM+ transac tio n isn’t muc h mo re diffic ult than that. Ho wever, to write
an effec tive COM+ applic atio n means that yo u need to kno w
what COM+ is and ho w it wo rks.
M ulti-tier applications
In a traditio nal c lient/ server applic atio n, the c lient c o mputer
c o mmunic ates direc tly with the database server (see Figure
18-1). This is also kno wn as a 2-tier applic atio n pro gram.
Client Computer
Database Server
Figure 18-1: A 2-tier application
Reviewing the
CO M+ transactio n
architecture
Meeting the
ACID test
Co nstructing CO M+
transactio ns
Building a test
pro g ram
✦
✦
✦
✦
370
Part IV ✦ COM + Transactions, and M essage Queues
By using COM+ transac tio ns, yo u c an implement a 3-tier so lutio n. In prac tic e, yo u
have a c o mputer fo r the c lient, a sec o nd o ne fo r the COM+ transac tio n server, and a
third o ne fo r the database server (see Figure 18-2). No te that the transac tio n server
generally sits between the applic atio n c lient and the database server.
Client Computer
Transaction Server
Database Server
Figure 18-2: A 3-tier application
The transac tio n server is a plac e where yo u c an mo ve yo ur applic atio n lo gic away
fro m the c lient pro gram yet keep it independent o f the database server. This
allo ws mo re flexibility when designing yo ur applic atio n, bec ause yo u c an pro vide
an o bjec t-o riented view o f yo ur data, while making available fac ilities that allo w
yo u to share reso urc es fo r better perfo rmanc e and permit transac tio n suppo rt fo r
better reliability.
A mo re interesting so lutio n is sho wn in Figure 18-3. While I’ve labeled it a 4-tier pro c essing so lutio n, mo st peo ple c o nsider it just ano ther variatio n o f a 3-tier so lutio n,
bec ause they feel that the c lient c o mputer running a Web bro wser is no t a true tier.
Ho wever, given ho w easy it is to add VBSc ript o r JavaSc ript to the Web page to perfo rm basic func tio ns like data validatio n, why no t c o nsider it a true tier?
In general, yo u c an refer to multi-tier so lutio ns as n-tier, where n refers to the number o f levels o f c o mputers used in the applic atio n design. No te that I do n’t simply
c o unt the number o f c o mputers, bec ause it is quite po ssible to have mo re than o ne
Web server, mo re than o ne transac tio n server o r mo re than o ne database server
that pro vides the same basic servic es, but are implemented o n multiple c o mputers
to better handle the wo rklo ad. With n-tier so lutio ns, eac h level o f c o mputers pro vides a new type o f servic e. In prac tic e, ho wever, eac h new level o f c o mputers intro duc es additio nal o verhead and beyo nd the fo ur c o mputers sho wn in Figure 18-3, it is
do ubtful that yo u wo uld gain any additio nal benefit fro m adding a new tier.
Chapter 18 ✦ Using COM + Transactions
Client Computer
Web Server
Transaction Server
Database Server
Figure 18-3: A 4-tier application
Transaction Servers
The transac tio n server rec eives requests fro m the pro gram running o n the c lient
and starts a transac tio n to pro c ess it. If info rmatio n is needed fro m the database
server, the transac tio n will c o mmunic ate with the database server. When the
transac tio n has finished pro c essing, it will return bac k to the c alling pro gram.
Adding the third tier, yo u o fflo ad so me o f the wo rk fro m the database server, whic h
allo ws the database server to perfo rm additio nal wo rk o n the same hardware c o nfiguratio n. It also simplifies updating the applic atio n, sinc e it is po ssible to make
c hanges to a transac tio n o n the transac tio n server witho ut c hanging the c lient pro gram that c alls the transac tio n.
In a 4-tier so lutio n, using a transac tio n server makes even mo re sense. It allo ws yo u
to o fflo ad wo rk fro m bo th the Web server and the database server o nto a separate
c o mputer system, whic h serves to impro ve respo nse time o n bo th mac hines. This
allo ws yo u to inc rease the available memo ry fo r Web page c ac hing and database
rec o rd c ac hing.
371
372
Part IV ✦ COM + Transactions, and M essage Queues
Typic ally, the database server, transac tio n server, and Web server (if present) are
all c o nnec ted via a very high-speed c o nnec tio n. At least a 100 MHz Ethernet, if no t
a gigahertz Ethernet o r o ther spec ialized netwo rking tec hno lo gy, is used to c o nnec t
these c o mputers to gether. Often this netwo rk is iso lated fro m the o ther netwo rks
to impro ve sec urity and perfo rmanc e. This means that there are very few delays
c aused by the netwo rk. Yet by spreading the wo rk aro und, yo u c an ensure that no
o ne system is o verlo aded. Yo u c an even add additio nal Web servers and transac tio n servers transparently if yo u really need them witho ut requiring c hanges to
yo ur applic atio n.
COM + applications
A COM+ transac tio n is basic ally a COM o bjec t that has been c o ded and c o mpiled
to run under the COM+ transac tio n server. In Visual Basic , yo u c reate a COM+ transac tio n by building an Ac tiveX DLL applic atio n. Yo u need to inc lude a few spec ial
o bjec ts and add a little c o de to perfo rm so me handshaking with the transac tio n
server and use a spec ial to o l to define yo ur transac tio n to the transac tio n server.
But o ther than that, yo u’re free to take advantage o f the Visual Basic language.
A COM+ applic atio n is just a c o llec tio n o f o ne o r mo re COM+ transac tio ns that are
gro uped to gether into a single Ac tiveX DLL file. There are fo ur basic types o f COM+
applic atio ns:
✦ Server applications: A server applic atio n is the mo re c o mmo n fo rm o f a
COM+ applic atio n. It runs under c o ntro l o f the transac tio n server. The applic atio n c an interac t with the transac tio n server thro ugh the o bjec ts asso c iated
with the transac tio n’s c o ntext.
✦ Library applications: A library applic atio n is a spec ialized fo rm o f a COM+
applic atio n that runs lo c ally o n the c lient c o mputer. It runs in the same
address spac e as the c lient pro gram that c reated it. This means less o verhead
to the c lient pro gram, bec ause several COM+ applic atio ns c an use the same
c o mpo nents. Ho wever, bec ause this o bjec t isn’t running under the c o ntro l o f
the transac tio n server, it c an’t take advantage o f so me o f the features o f the
transac tio n server.
✦ Application proxies: An applic atio n pro xy c o ntains the registratio n info rmatio n nec essary fo r an applic atio n to remo tely ac c ess a server applic atio n. If
yo u run it o n the c lient c o mputer, all o f the info rmatio n nec essary to ac c ess
a spec ific remo te server applic atio n will be installed o n the c lient c o mputer.
✦ COM+ preinstalled applications: COM+ c o mes with a set o f applic atio ns that
help yo u c o nfigure and administer yo ur COM+ system. These applic atio ns
inc lude COM+ System Administratio n, COM+ Utilities, and IIS System
Applic atio ns.
Of these types o f COM+ applic atio ns, I’m go ing to fo c us o n server applic atio ns,
sinc e they are the mo st useful o f all.
Chapter 18 ✦ Using COM + Transactions
The COM + transaction server
The COM+ Transac tio n Server pro vides a framewo rk to exec ute transac tio ns o n an
n-tier applic atio n system. Inc luded with the Server are fac ilities that allo w yo u to
share reso urc es, suc h as ASO Connection o bjec ts, and pro vide additio nal sec urity
o n yo ur transac tio n.
Yo u c an o nly run the COM+ Transac tio n Server under Windo ws 2000 Server. Yo u
c an’t run it under Windo ws 9x, Windo ws NT, o r even Windo ws 2000 Pro fessio nal. It
relies o n fac ilities, suc h as the Ac tive Direc to ry, to manage muc h o f the info rmatio n
it needs to run yo ur transac tio ns. Bec ause the COM+ Transac tio n Server represents
o nly o ne tier in an applic atio n, yo u c an use any database server yo u c ho o se, even if
it runs under a different o perating system suc h as Unix. The o nly restric tio n is that
the database server must be suppo rted by ADO.
Note
Serving transactions under Windows NT: If you w ant to run transactions under
Window s NT Server, you need to use a tool called Microsoft Transaction Server,
usually called MTS. Many of the basic facilities in MTS w ere upgraded to create
COM+ , but COM+ is not upw ards com patible w ith MTS. COM+ requires less code
to interact w ith the transaction server and is easier to adm inister than MTS.
The object context
Every COM+ transac tio n that is run under c o ntro l o f the COM+ Transac tio n Server
is asso c iated with a set o f o bjec ts kno wn as a co nte xt. A c o ntext represents the
smallest po ssible unit o f wo rk fo r a c o mpo nent. Eac h instanc e o f a COM o bjec t is
assigned to a c o ntext. Multiple o bjec ts c an use the same c o ntext depending o n ho w
they were defined and c reated.
The o bjec t c o ntext c o ntains info rmatio n abo ut ho w the o bjec t was c reated and the
status o f the wo rk that is c urrently ac tive. Yo u c an ac c ess these fac ilities thro ugh
the ObjectContext o bjec t. All o f the o ther o bjec ts in the c o ntext c an be referenc ed
fro m this o bjec t either direc tly o r indirec tly.
The Component Services utility
The Co mpo nent Servic es utility is used to manage and c o nfigure COM+ transac tio ns (see Figure 18-4). Yo u c an start it in Windo ws 2000 by c ho o sing Pro grams ➪
Administrative To o ls ➪ Co mpo nent Servic es fro m the Start butto n. This to o l will be
used frequently while testing yo ur applic atio n to c hange the c harac teristic s o f the
transac tio n, as well as to install updated c o pies o f the COM c o mpo nent that makes
up yo ur COM+ applic atio n.
373
374
Part IV ✦ COM + Transactions, and M essage Queues
Figure 18-4: Running the Com ponent Services utility
Introducing COM + Transactions
COM+ transac tio ns are a feature o f Windo ws 2000 that yo u c an use when building
sc alable, n-tier applic atio ns. COM+ is built o n to p o f COM and integrates features
suc h as the Mic ro so ft Transac tio n Server and Mic ro so ft Message Queues into a
single tec hno lo gy.
COM+ is built using C++ and so me o f its features c an o nly be ac c essed fro m C++.
Ho wever, this do esn’t mean that yo u c an’t use COM+ fro m Visual Basic 6. In fac t,
many o f the features are ac tually very easy to use, o nc e yo u understand ho w to
wo rk with them. Bec ause this bo o k is aimed at Visual Basic pro grammers, I’ll fo c us
o n the features yo u c an explo it to day and leave the rest fo r the C++ pro grammers.
Note
A view of things to come: As I w rite this, there are m any rum ors surrounding
the features that w ill be present in Visual Basic 7. While it isn’t clear exactly w hat
features w ill be present, you can bet that support for COM+ w ill be at the top of
the list.
In Chapter 16, I talked abo ut ho w to use the BeginTransaction, CommitTransaction,
and RollbackTransaction metho ds to define a transac tio n o ver a database c o nnec tio n. These transac tio ns represented a fundamental unit o f wo rk fo r the applic atio n.
Chapter 18 ✦ Using COM + Transactions
They c o uld c o ntain the database c alls nec essary to make a withdrawal fro m yo ur
savings ac c o unt, register yo u fo r a c o llege c o urse, o r even o rder a bo o k o ver the
Internet.
Simply lo o king at a transac tio n fro m a database perspec tive may be a bit to o limiting
fo r many applic atio ns. In additio n to manipulating data in the database, transac tio ns
o ften perfo rm validatio n alo ng with the database ac tivities. Fo r example, befo re making a withdrawal fro m yo ur c hec king ac c o unt, yo u must first verify that the ac c o unt
number is valid, and sec o nd, that there are suffic ient funds in the c hec king ac c o unt
befo re subtrac ting the mo ney fro m that ac c o unt.
There are a several ways to implement a transac tio n. The mo st c o mmo n way is to
write c o mplex sto red pro c edures that run o n the database server. This appro ac h
impo ses extra wo rk o n the database server, whic h may detrac t fro m the database
server’s o verall perfo rmanc e. In Windo ws 2000, yo u have the o ptio n o f building
COM+ transac tio ns that run under c o ntro l o f a transac tio n server, whic h yo u c an
easily run o n a separate mac hine.
The ACID test
Eac h COM+ transac tio n must meet the ACID test. The letters in ACID stand fo r
Ato mic ity, Co nsistenc y, Iso latio n, and Durab ility, and serve to identify the different c riteria that a transac tio n must meet.
Atomicity
Ato micity means that either all o r no ne o f a transac tio n is c o mpleted. In o ther wo rds,
the wo rk a transac tio n perfo rms c an’t be subdivided. If the transac tio n c o mpletes
suc c essfully, all o f the c hanges it makes will remain. If the transac tio n fails, then all
o f the c hanges it made must be undo ne.
Co nsider an airline reservatio ns system. When yo u make a reservatio n, yo u spec ify
the date, flight number, number o f seats yo u want, plus a number o f parameters
suc h as first c lass o r ec o no my. Yo u want the reservatio n to suc c eed o nly if all o f
these parameters are met. Otherwise yo u want the reservatio n to fail, so yo u c an
try again. Either all o f the seats yo u requested are available o r no ne o f them.
Consistency
Ano ther aspec t o f a transac tio n is that it must always leave the system in a c o nsistent state. Co nsider what happens if yo u mo ve mo ney fro m yo ur savings ac c o unt
to yo ur c hec king ac c o unt. Yo u have to read the c urrent balanc e fro m the savings
ac c o unt, subtrac t the amo unt o f mo ney yo u want to mo ve, and update the ac c o unt
with the new balanc e. Then yo u have to read the c urrent balanc e fro m the c hec king
ac c o unt, add the mo ney to it, and update the ac c o unt with the new balanc e.
375
376
Part IV ✦ COM + Transactions, and M essage Queues
Co nsider what happens if the pro c ess fails after the first update is finished, but
befo re the sec o nd update is made. The database will auto matic ally ensure that the
first update is saved, but it will no t save an inc o mplete update. This means that the
mo ney wo uld be remo ved fro m yo ur saving ac c o unt but no t added to yo ur c hec king ac c o unt. Fo r all prac tic al purpo ses, the mo ney wo uld be lo st and the database
left in an inc o nsistent state.
By plac ing the two updates into a transac tio n, yo u c an ensure that the database is
left in a c o nsistent state. Either bo th updates are c o mpleted o r bo th updates are
no t c o mpleted. In this example, whether the transac tio n suc c eeds o r fails, the
mo ney wo n’t be lo st.
Isolation
While no t as o bvio us as the previo us c harac teristic s o f a transac tio n, iso latio n is
also very impo rtant. Eac h transac tio n lives in its o wn wo rld, where it c an’t see any
o f the pro c essing perfo rmed by ano ther ac tive transac tio n. The c o nc ept o f iso latio n
is impo rtant bec ause it allo ws the system to rec o ver fro m failures. While the system
is ac tively pro c essing transac tio ns, yo u may have do zens o r even hundreds o f
ac tive transac tio ns at any po int in time. Ho wever, with transac tio n iso latio n, these
transac tio ns c an be viewed as a single stream o f transac tio ns, where o ne transac tio n is c o mpleted befo re the next o ne begins. This pro c ess allo ws rec o very pro grams to wo rk, and makes it po ssible to implement distributed database systems.
Durability
The last c harac teristic o f a transac tio n is its ability to survive system failures. Onc e
a transac tio n has been c o mpleted, it is c ritic al that the c hanges it made aren’t lo st.
Fo r this reaso n, it’s impo rtant that the system keep lo gs and bac kups o f all the transac tio ns that were pro c essed. These files make it po ssible fo r wo rk to be rec o vered in
c ase o f a c atastro phic system failure.
Class module properties for transactions
In o rder to identify a Visual Basic c lass mo dule as a COM+ transac tio n, yo u need to
adjust so me o f its pro perties. These pro perties c o ntro l ho w Visual Basic will c o mpile yo ur pro gram.
In o rder to run a transac tio n under c o ntro l o f COM+ yo u need to spec ify the value
o f the MTSTransactionMode pro perty in the c lass mo dule. While this value c an be
o verridden by the Co mpo nent Servic es utility, yo u sho uld c ho o se the pro per value
befo re yo u try to install it under COM+. Table 18-1 lists the Visual Basic c o nstant
that yo u c an set using the Pro perties windo w fo r the c lass mo dule.
Chapter 18 ✦ Using COM + Transactions
Table 18-1
M TSTransactionM ode Values
Visual Basic Constant
COM + Transaction Support
Numeric Value
NotAnMTSObject
Disabled
0
NoTransactions
Not Supported
1
RequiresTransaction
Required
2
UsesTransaction
Supported
3
RequiresNewTransaction
Requires New
4
✦ NotAnMTSObje ct implies that the o b jec t isn’t suppo rted under COM+
Transac tio n Server. Yo u sho uld use this value when yo u do no t expec t to
run yo ur c o mpo nent under c o ntro l o f the Transac tio n Server.
✦ NoTransactions means that the o bjec t do esn’t suppo rt transac tio ns. When a
new instanc e o f the o bjec t is c reated, its o bjec t c o ntext is c reated witho ut a
transac tio n.
✦ RequiresTransaction means that the c o mpo nent’s o bjec ts must exec ute witho ut the sc o pe o f a transac tio n. When a new instanc e o f the o bjec t is c reated,
the o bjec t c o ntext is inherited fro m the o bjec t c o ntext o f the c lient. If the
c lient do esn’t have a transac tio n, a new transac tio n is c reated fo r the o bjec t.
If the c lient is a COM+ transac tio n, then a new transac tio n will no t be started
bec ause o ne is already ac tive.
✦ UsesTransaction means that the c o mpo nent’s o bjec ts c an exec ute within the
sc o pe o f a transac tio n. When a new instanc e o f the o bjec t is c reated, its o bjec t
c o ntext is inherited fro m the o bjec t c o ntext o f the c lient. If the c lient do esn’t
have a transac tio n, the new o bjec t will run witho ut a transac tio n.
✦ RequiresNewTransaction means that the c o mpo nent’s o bjec ts must exec ute
within their o wn transac tio ns. When a new instanc e o f the o bjec t is c reated, a
new transac tio n will auto matic ally be c reated fo r the o bjec t, even if the c alling
o bjec t is already exec uting within a transac tio n.
The ObjectContext object
The ObjectContext o bjec t is the mo st impo rtant o bjec t when implementing a
COM+ transac tio n. Thro ugh this o bjec t, yo u will c o ntro l ho w the transac tio n
behaves. Yo u c an use this o bjec t to c o mmunic ate with the transac tio n server and
find o ut info rmatio n abo ut the enviro nment in whic h it is running.
377
378
Part IV ✦ COM + Transactions, and M essage Queues
Yo u c an get ac c ess to this o bjec t by selec ting the COM+ Servic es Type Library
fro m the Referenc es windo w by c ho o sing Pro jec t ÿ Referenc es fro m the Visual
Basic main menu ( see Figure 18-5) and then dec laring and c alling the
GetObjectContext func tio n, as sho wn belo w:
Dim MyContext As ObjectContext
Set MyContext = GetObjectContext()
Figure 18-5: Selecting the COM+
Services Type Library
ObjectContext object properties
Table 18-2 lists the pro perties o f the ObjectContext o bjec t.
Table 18-2
Properties of the ObjectContext Object
Property
Description
ContextInfo
An object reference to the ContextInfo object.
Count
A Long value containing the num ber of property objects.
Item
An object reference to a specific property object.
Security
An object reference to the SecurityProperty object.
ObjectContext object methods
Of the metho ds available fo r the ObjectContext o bjec t, the mo st impo rtant are
SetAbort and SetComplete. These instruc t the transac tio n server whether to
allo w the transac tio n’s ac tivities to be saved o r undo ne.
Chapter 18 ✦ Using COM + Transactions
Function CreateInstance (bstrProgID As String) As Variant
The CreateInstance metho d returns an o b jec t referenc e to a new instanc e o f
the spec ified o b jec t using the c urrent o b jec t’s c o ntext. This func tio n sho uld b e
used in plac e o f the CreateObject func tio n, b ec ause it implements the c urrent
c o ntext fo r its exec utio n. If the o b jec t isn’t registered with COM+, the o b jec t is
merely c reated and no c o ntext will b e assigned. If the o b jec t is registered with
COM+, it will b e c reated ac c o rding to the COM+ Transac tio n Suppo rt value and
the MTSTransactionMode pro perty. bstrProgID is a String value c o ntaining
the name o f the o b jec t to b e c reated.
Sub DisableCommit( )
The DisableCommit metho d tells the transac tio n server that the o bjec t’s wo rk has
left the system in an inc o nsistent state.
Sub EnableCommit( )
The EnableCommit metho d tells the transac tio n server that the o bjec t’s wo rk may
no t be c o mplete, but that the system is no w in a c o nsistent state.
Function IsCallerInRole(bstrRole As String) As Boolean
The IsCallerInRole metho d returns True when the o bjec t’s direc t c aller is in the
spec ified ro le, either individually o r as part o f a gro up. bstrRole is a String value
c o ntaining the sec urity ro le.
Function IsInTransaction( ) As Boolean
The IsInTransaction metho d is True when the o bjec t is exec uting inside a transac tio n.
Function IsSecurityEnabled ( ) As Boolean
The IsSecurityEnabled metho d is True when sec urity is enabled.
Sub SetAbort( )
The SetAbort metho d instruc ts the transac tio n server to undo any o f the transac tio n’s ac tio ns. This may be bec ause an unrec o verable erro r has o c c urred o r the system is in an inc o nsistent state.
Sub SetComplete( )
The SetComplete metho d instruc ts the transac tio n server to c o mmit all updates to
the system bec ause the transac tio n has c o mpleted its wo rk suc c essfully.
379
380
Part IV ✦ COM + Transactions, and M essage Queues
Constructing a COM + Transaction
Co nstruc ting a COM+ transac tio n is fairly easy. Yo u start by c reating an Ac tiveX DLL
pro jec t to ho ld the transac tio n. If yo u want to pass any o bjec ts between the transac tio n and the pro gram, yo u will need a sec o nd Ac tiveX DLL to ho ld the type info rmatio n. Finally, to test yo ur transac tio n, yo u’ll need a simple applic atio n that c alls
the transac tio n.
Fo r this example, I’m go ing to use the Custo mers table and c reate COM+ transac tio ns to retrieve a single c usto mer and to update a single c usto mer. The info rmatio n will be passed bac k and fo rth between the c lient and the transac tio n server
using the Custo mer o bjec t. To demo nstrate the transac tio ns, I’m also go ing to
build a simple IIS Applic atio n and run it thro ugh the IIS Web server.
Holding type information
One pro blem yo u will enc o unter when yo u begin using COM+ transac tio ns is that
yo u c an’t rely o n glo bal variables to pass info rmatio n bac k and fo rth to the ro utines
yo u may c all. Everything must be passed as a parameter. Depending o n the data
yo u want to share with a ro utine, this c an be a pro blem.
Using Visual Basic ’s c lass mo dules, yo u c an c reate an o bjec t that c o ntains a lo t o f
info rmatio n in a single entity. When using so me o f the mo re advanc ed features in
Windo ws, suc h as COM+ transac tio ns and message queuing, this is my favo rite way
to pass info rmatio n aro und.
The do wnside to using c lass mo dules to pass info rmatio n aro und in a COM+ transac tio n is that yo u really have to deal with two different pro grams. The COM+ transac tio n o perates independently o f the applic atio n pro gram using the transac tio n.
Therefo re, bo th pro grams need a c o py o f the definitio ns. The o nly reaso nable way
to handle this situatio n is to intro duc e a third c o de mo dule that ho lds the type definitio ns fo r yo ur transac tio ns. This third mo dule exists o n bo th the c lient mac hine
and the transac tio n server mac hine.
Creating storage for property values
Like any o b jec t, the Custo mer o b jec t c o nsists o f a series o f Public Property
Get and Property Let ro utines, whic h are used to ac c ess a b unc h o f Private
variab les defined at the mo dule level. Listing 18-1 c o ntains the list o f Private
variab les. No te that eac h o f the variab le names b egins with an X. This is b ec ause I
wanted the o b jec t’s user to see the field names I used in the datab ase rather than
use a c ryptic ab b reviatio n. Sinc e I’m the o nly perso n who expec ts to see inside
the Custo mer o b jec t, I do n’t c o nsider this a real hardship.
Chapter 18 ✦ Using COM + Transactions
Listing 18-1: The module level declarations in Customer
Option Explicit
Private
Private
Private
Private
Private
Private
Private
Private
Private
Private
Private
Private
Private
XCustomerID As Long
XName As String
XStreet As String
XCity As String
XState As String
XZip As Long
XPhone As String
XEMailAddress As String
XDateAdded As Date
XDateUpdated As Date
XMailingList As Boolean
XComments As String
XIsDirty As Boolean
Yo u sho uld no te that in additio n to the vario us fields fro m the database, I also
added o ne mo re value, c alled XIsDirty. The XIsDirty pro perty is used to indic ate
when the data in the o bjec t has been c hanged. It’s a quic k and easy way to determine if the info rmatio n was c hanged and the database sho uld be updated.
M anaging property values
The Property Get ro utine just returns the value o f the c o rrespo nding X variable
(see Listing 18-2), while the Property Let ro utine is a little mo re c o mplic ated (see
Listing 18-3).
The Property Let ro utine determines if the value o f the pro perty is different than
the value already in private sto rage. If the value is different, then I save the new value,
set the XIsDirty pro perty, and mark the pro perty as c hanged. Otherwise, I igno re
the assignment. While c hec king the assignment is a little extra wo rk, it allo ws so meo ne to reassign the c urrent value to the pro perty witho ut resetting the XIsDirty flag.
Listing 18-2: The CustomerId Property Get
routine in Customer
Public Property Get CustomerId() As Long
CustomerId = XCustomerID
End Property
381
382
Part IV ✦ COM + Transactions, and M essage Queues
Listing 18-3: The CustomerId Property Let
routine in Customer
Public Property Let CustomerId(c As Long)
If c XCustomerID Then
XCustomerID = c
XIsDirty = True
PropertyChanged “CustomerId”
End If
End Property
Note
Property M ay I: The CanPropertyChange m ethod isn’t required w hen dealing
w ith properties in the Customer object, since the Customer object can’t act as a
data consum er.
Initializing property values
I c ho se to make the Custo mers o bjec t a persistable o bjec t. This will have a big benefit later when I talk abo ut message queuing in Chapter 19. Ho wever, fo r no rmal
COM+ transac tio ns, yo u do n’t really need persistent o bjec ts. Onc e the o bjec t is
instantiated, it will remain instantiated until yo u destro y it.
Listing 18-4 c o ntains the statements nec essary to initialize the variables in lo c al
sto rage. No te that I just use reaso nable default values fo r all o f these pro perties
exc ept fo r XDateAdded and XDateUpdated. Fo r these values, I use the func tio n Now
to save the c urrent date and time into these variables. This makes it easier fo r
so meo ne to c reate a new Custo mer o bjec t and no t wo rry abo ut assigning values to
these two fields. It also wo n’t c ause a pro blem when the COM+ transac tio n returns
info rmatio n fro m the database, sinc e these initial values will be o verlaid with the
live values fro m the database.
Listing 18-4: The Class_InitProperties event in Customer
Private Sub Class_InitProperties()
XCustomerID = -1
XName = “”
XStreet = “”
XCity = “”
XState = “”
Chapter 18 ✦ Using COM + Transactions
XZip = 0
XPhone = “”
XEMailAddress = “”
XDateAdded = Now
XDateUpdated = Now
XMailingList = False
XComments = “”
XIsDirty = False
End Sub
As yo u wo uld expec t, the ReadProperties and WriteProperties events are pretty
simple, just a series o f statement that use the ReadProperty and WriteProperty
metho ds to resto re and save these values. Listing 18-5 sho ws the ReadProperties
event.
Listing 18-5: The Class_ReadProperties event in Customer
Private Sub Class_ReadProperties(PropBag As PropertyBag)
XCustomerID = PropBag.ReadProperty(“CustomerId”, 0)
XName = PropBag.ReadProperty(“Name”, “”)
XStreet = PropBag.ReadProperty(“Street”, “”)
XCity = PropBag.ReadProperty(“City”, “”)
XState = PropBag.ReadProperty(“State”, “”)
XZip = PropBag.ReadProperty(“Zip”, 0)
XPhone = PropBag.ReadProperty(“Phone”, “”)
XEMailAddress = PropBag.ReadProperty(“EMailAddress”, “”)
XDateAdded = PropBag.ReadProperty(“DateAdded”, 0)
XDateUpdated = PropBag.ReadProperty(“DateUpdated”, 0)
XMailingList = PropBag.ReadProperty(“MailingList”, False)
XComments = PropBag.ReadProperty(“Comments”, “”)
XIsDirty = False
End Sub
No te that even tho ugh I assign the c urrent date and time in the InitProperties
event to the DateAdded and DateUpdated pro perties, I use a default value o f
zero . This just means that these pro perties will always b e sto red in the pro perty
b ag, whic h is likely to happen anyway, given the nature o f the data sto red in the
pro perties.
383
384
Part IV ✦ COM + Transactions, and M essage Queues
Installing the DLL
Onc e yo u build yo ur pro gram, yo u need to c o mpile it to an Ac tiveX DLL (Dynamic
Linking Library) and then register it in the Windo ws Registry. When yo u register
yo ur DLL, selec ted info rmatio n abo ut the DLL will be lo aded into the Registry,
inc luding the lo c atio n o f the DLL file, the name o f the o bjec ts available, and the
Glo bally Unique Identifiers (GUID) that are used to lo c ate them.
When yo ur pro gram referenc es an o bjec t, it presents the o bjec t’s GUID to Windo ws,
whic h in turn uses it as a key to lo c ate info rmatio n abo ut the o bjec t in the Registry.
This means that the ac tual lo c atio n o f the file c an be independent o f the applic atio n.
To register yo ur file, yo u need to use the RegSvr32 utility pro gram. To run it, c ho o se
Start ➪ Run fro m the Windo ws taskbar. Then enter the RegSvr32 fo llo wed by the
fully qualified path name to the DLL file, as sho wn belo w:
RegSvr32 d:\VB6DB\Chapter18\CustomerObjects\cust.dll
and press Enter. The registratio n pro gram will run fo r a split sec o nd and display a
message bo x saying that RegisterDLL Server suc c eeded.
If yo u need to make a c hange to the DLL after yo u have registered it, yo u must run
the fo llo wing c o mmand:
RegSvr32 /u d:\VB6DB\Chapter18\CustomerObjects\cust.dll
It will ac kno wledge the request by saying DLLUnregister Server suc c eeded.
Tip
DOS ain’t dead: After using DOS and m any other character operating system s
over the years, I actually like typing m y com m ands and seeing the results. I often
use DOS to display directory inform ation and to copy files, and as a result, I usually have a DOS w indow open. So rather than choosing Start ➪ Run, I usually just
toggle to m y DOS w indow to run the RegSvr32 com m and. Besides, if the DLL is in
the current directory, I need only type the file nam e rather than the fully qualified
path nam e.
Accessing the database with transactions
No w that I have an o bjec t I c an pass bac k and fo rth to COM+ transac tio ns, I want to
build so me transac tio ns. Fo r all prac tic al purpo ses, building a COM+ transac tio n is
just like building any o ther COM c o mpo nent that ac c esses a database — with two
exc eptio ns. First, yo u need to use the ObjectContext o bjec t to info rm the transac tio n server o f the transac tio n’s status. Sec o nd, yo u need to grab and release
database reso urc es, suc h as the Co nnec tio n o bjec t, quic kly.
Chapter 18 ✦ Using COM + Transactions
Getting customer information
The GetCustomer metho d (see Listing 18-6) retrieves the c usto mer info rmatio n fo r
the c usto mer spec ified in the CustomerId parameter and returns it to the c alling
pro gram using the Custo mer o bjec t. While a metho d that stric tly reads info rmatio n
fro m the database do esn’t benefit fro m the COM+ transac tio n server’s ability to
manage c o mplex transac tio ns, it do es allo w this ro utine to o perate mo re effic iently
than it wo uld if yo u embedded the c o de direc tly in yo ur applic atio n pro gram.
Listing 18-6: The GetCustomer method of CustomerInfo
Public Function GetCustomer(CustomerId As Long) As Customer
Dim
Dim
Dim
Dim
Dim
Dim
c As Customer
cmd As ADODB.Command
db As ADODB.Connection
o As ObjectContext
parm As ADODB.Parameter
rs As ADODB.Recordset
Set o = GetObjectContext()
Err.Clear
Set db = New ADODB.Connection
db.Provider = “sqloledb”
db.ConnectionString = “Athena”
db.CursorLocation = adUseNone
db.Open , “sa”, “”
db.DefaultDatabase = “VB6DB”
Set cmd = New ADODB.Command
Set cmd.ActiveConnection = db
cmd.CommandText = “Select * from Customers “ & _
“Where CustomerId = ?”
Set parm = cmd.CreateParameter(“CustomerId”, adInteger, _
adParamInput, 4)
cmd.Parameters.Append parm
Err.Clear
cmd.Parameters(“CustomerId”).Value = CustomerId
Set rs = cmd.Execute
If Err.Number 0 Then
App.LogEvent “CustomerInfo(GetCustomer): “ & _
“Can’t retrieve the “ & _
“record for CustomerId “ & _
FormatNumber(CustomerId, 0) & “. Error: “ & _
Err.Description & “-” & _
Hex(Err.Number)
Continued
385
386
Part IV ✦ COM + Transactions, and M essage Queues
Listing 18-6 (continued)
Set c = Nothing
Else
Set c = New Customer
c.CustomerId = rs.Fields(“CustomerId”)
c.Name = rs.Fields(“Name”)
c.Street = rs.Fields(“Street”)
c.City = rs.Fields(“City”)
c.State = rs.Fields(“State”)
c.Zip = rs.Fields(“Zip”)
c.Phone = rs.Fields(“Phone”)
c.EMailAddress = rs.Fields(“EMailAddress”)
c.DateAdded = rs.Fields(“DateAdded”)
c.DateUpdated = rs.Fields(“DateUpdated”)
c.MailingList = rs.Fields(“MailingList”)
c.Comments = rs.Fields(“Comments”)
End If
Set GetCustomer = c
rs.Close
db.Close
Set rs = Nothing
Set db = Nothing
Set c = Nothing
Set o = Nothing
End Function
The GetCustomer metho d begins by dec laring a number o f o bjec ts that I’ll use in
this pro gram. Next, I’ll get an o bjec t referenc e to the ObjectContext fo r this transac tio n. While I do n’t really need it, it isn’t a bad idea to get in the habit o f starting
every metho d by getting the c o ntext.
Next, I establish a c o nnec tio n to the database. Rather than c reating a c o nnec tio n
o nc e and using it fo r all transac tio ns that this o bjec t might exec ute, it is mo re effic ient to get a c o nnec tio n, use it, and then release it as quic kly as po ssible. The
COM+ transac tio n server interc epts yo ur c all and satisfies yo ur request with an
existing c o nnec tio n fro m a po o l o f c o nnec tio ns it maintains. When yo u release the
c o nnec tio n, the COM+ transac tio n server adds it bac k to the po o l and makes it available fo r so meo ne else to use. By sharing c o nnec tio ns in this fashio n, bo th yo ur
applic atio n and the database server have a lo t less wo rk to do .
Chapter 18 ✦ Using COM + Transactions
After the c o nnec tio n is o pened, I c reate a Command o bjec t with a parameterized
Select statement and its asso c iated Parameter o bjec t. I c ho se to use the Command
o bjec t rather than a Recordset bec ause the Command o bjec t will be mo re effic ient
in the lo ng run. SQL Server 7 will parse the query the first time it sees it, and the
next time I use the query, it will be able to use the already parsed versio n. This
makes it nearly as fast as a sto red pro c edure, witho ut the headac hes o f c reating a
sto red pro c edure.
When I exec ute the Command, it will return a Recordset o bjec t c o ntaining the
value I requested, in whic h c ase I’ll save the values into a Customer o bjec t and
return it as the value o f the func tio n. If exec uting the Command generated an erro r,
I’ll write the erro r to the applic atio n’s lo g file and return Nothing as the value o f
the func tio n.
At the end o f the func tio n, I c lo se the Recordset and Connection o bjec ts and destro y
all o f the o bjec ts I used in the ro utine. No te that I destro y the ObjectContext o bjec t,
sinc e it is no lo nger nec essary. A c all to SetComplete o r SetAbort isn’t nec essary
sinc e I didn’t mo dify any data.
Saving customer information
The PutCustomer metho d sho wn in Listing 18-7 fo llo ws the same basic lo gic flo w
as the GetCustomer metho d yo u saw in 18-6. I begin by ac quiring a c o nnec tio n to
the database. Then I c reate a Command o bjec t that exec utes an SQL Update statement. Next I assign the appro priate values fro m the Customer o bjec t to the parameters in the c o mmand and then exec ute the Update statement. Finally, I return any
erro r info rmatio n as the value o f the func tio n, signal the ObjectContext that the
transac tio n is c o mplete and destro y the o bjec ts I used.
Listing 18-7: The PutCustomer method of CustomerInfo
Public Function PutCustomer(c As Customer) As Long
On Error Resume Next
Dim
Dim
Dim
Dim
cmd As ADODB.Command
db As ADODB.Connection
o As ObjectContext
parm As ADODB.Parameter
Set o = GetObjectContext()
PutCustomer = 0
Err.Clear
Continued
387
388
Part IV ✦ COM + Transactions, and M essage Queues
Listing 18-7 (continued)
Set db = New ADODB.Connection
db.Provider = “sqloledb”
db.ConnectionString = “Athena”
db.CursorLocation = adUseNone
db.Open , “sa”, “”
db.DefaultDatabase = “VB6DB”
Set cmd = New ADODB.Command
Set cmd.ActiveConnection = db
cmd.CommandText = “Update Customers Set Name=?, Street=?, “ _
“City=?, State=?, “ & _
“Zip=?, Phone=?, EMailAddress=?, DateAdded=?, “ & _
“DateUpdated=?, MailingList=?, Comments=? “ & _
“Where CustomerId=?”
Set parm = cmd.CreateParameter(“Name”, adVarChar, _
adParamInput, 64)
cmd.Parameters.Append parm
Set parm = cmd.CreateParameter(“Street”, adVarChar, _
adParamInput, 64)
cmd.Parameters.Append parm
Set parm = cmd.CreateParameter(“City”, adVarChar, _
adParamInput, 64)
cmd.Parameters.Append parm
Set parm = cmd.CreateParameter(“State”, adChar, _
adParamInput, 2)
cmd.Parameters.Append parm
Set parm = cmd.CreateParameter(“Zip”, adInteger, _
adParamInput, 4)
cmd.Parameters.Append parm
Set parm = cmd.CreateParameter(“Phone”, adVarChar, _
adParamInput, 32)
cmd.Parameters.Append parm
Set parm = cmd.CreateParameter(“EMailAddress”, adVarChar, _
adParamInput, 128)
cmd.Parameters.Append parm
Set parm = cmd.CreateParameter(“DateAdded”, adDBDate, _
adParamInput)
cmd.Parameters.Append parm
Chapter 18 ✦ Using COM + Transactions
Set parm = cmd.CreateParameter(“DateUpdated”, adDBDate, _
adParamInput)
cmd.Parameters.Append parm
Set parm = cmd.CreateParameter(“MailingList”, adBoolean, _
adParamInput)
cmd.Parameters.Append parm
Set parm = cmd.CreateParameter(“Comments”, adVarChar, _
adParamInput, 256)
cmd.Parameters.Append parm
Set parm = cmd.CreateParameter(“CustomerId”, adInteger, _
adParamInput, 4)
cmd.Parameters.Append parm
cmd.Parameters(“CustomerId”).Value = c.CustomerId
cmd.Parameters(“Name”).Value = c.Name
cmd.Parameters(“Street”).Value = c.Street
cmd.Parameters(“City”).Value = c.City
cmd.Parameters(“State”).Value = c.State
cmd.Parameters(“Zip”).Value = c.Zip
cmd.Parameters(“Phone”).Value = c.Phone
cmd.Parameters(“EMailAddress”).Value = c.EMailAddress
cmd.Parameters(“DateAdded”).Value = c.DateAdded
cmd.Parameters(“DateUpdated”).Value = c.DateUpdated
cmd.Parameters(“MailingList”).Value = c.MailingList
cmd.Parameters(“Comments”).Value = c.Comments
cmd.Execute
If Err.Number 0 Then
App.LogEvent _
“Customer(PutCustomer): Can’t update the record “ & _
“for CustomerId “ & _
FormatNumber(c.CustomerId, 0) & “. Error: “ & _
Err.Description & “-” & _
Hex(Err.Number)
PutCustomer = Err.Number
End If
db.Close
o.SetComplete
Set cmd = Nothing
Set db = Nothing
Set o = Nothing
End Function
389
390
Part IV ✦ COM + Transactions, and M essage Queues
Yo u may be wo ndering why I c ho se to use the Update statement, rather than
update the database using a Recordset o bjec t. The answer is really simple: the
Update statement is mo re effic ient in this situatio n. In o rder to use a Recordset,
yo u wo uld have to retrieve the rec o rds a sec o nd time. Then yo u wo uld have to
c hange the values in the c urrent rec o rd and use the Update metho d to send the
c hanges bac k to the database. In this c ase, simply send the update direc tly to the
server.
Installing the transaction into COM +
The COM+ transac tio n server is managed by using the Co mpo nent Servic es utility.
Yo u c an ac c ess this utility by c ho o sing Start ➪ Pro grams ➪ Administrative To o ls ➪
Co mpo nent Servic es (see Figure 18-4).
To add yo ur applic atio n to the COM+ transac tio n server, yo u need to perfo rm these
steps:
1. Cho o se Start ➪ Pro grams ➪ Administrative To o ls ➪ Co mpo nent Servic es fro m
the Windo ws taskbar.
2. Under Co nso le Ro o t, o pen COM+ Applic atio ns by selec ting Co mpo nent
Servic es, then Co mputers and the name o f the c o mputer o n whic h yo u want
to c reate servic e.
3. Right c lic k o n Co mpo nent Servic es and c ho o se New ➪ Applic atio n fro m the
po p-up menu. This starts the COM Applic atio n Install Wizard.
4. Press Next fro m the welc o me sc reen and then c lic k o n the Create an empty
applic atio n butto n.
5. On the Create Empty Applic atio n windo w, enter the name fo r yo ur new applic atio n and c ho o se Server Applic atio n (see Figure 18-6).
6. Clic k Next to display the Set Applic atio n Identity windo w sho wn in Figure 18-7.
Cho o se the user ac c o unt under whic h the applic atio n will run. Yo u c an c ho o se
to use the sec urity o f the user name who is lo gged o nto the server’s c o nso le
(the interac tive user) when the applic atio n is run. Yo u may also enter the name
and passwo rd o f a spec ific user. Clic k Next to go to the last step o f the wizard.
7. Clic k Finish to install the empty applic atio n.
Note
Security can be difficult: For testing purposes, I suggest that you use the user
nam e of the interactive user logged onto the server’s console. Then you should
sign on as Adm inistrator (or another user nam e w ith the sam e privileges as
Adm inistrator). This w ill rem ove m ost of the security restrictions on your transactions. Once the transactions have been debugged, you can go back and create a
specific user nam e w ith only the privileges needed to run the transaction.
Chapter 18 ✦ Using COM + Transactions
Figure 18-6: Entering the nam e of the application
Figure 18-7: Associating the application w ith a
user nam e
Onc e yo u have an empty applic atio n, yo u need to impo rt yo ur Ac tiveX DLL using
these steps in the Co mpo nent Servic es utility (c ho o se Start ➪ Pro grams ➪
Administrative To o ls ➪ Co mpo nent Servic es in Windo ws 2000).
1. Expand the applic atio n yo u just c reated to display the Co mpo nents and Ro les
fo lders beneath it.
2. Right c lic k o n the Co mpo nents fo lder and selec t New ➪ Co mpo nent fro m the
po p-up menu. This will start the COM Co mpo nent Install Wizard.
391
392
Part IV ✦ COM + Transactions, and M essage Queues
3. Clic k Next to mo ve to the Impo rt o r Install a Co mpo nent step and c lic k o n
Install New Co mpo nent(s) butto n.
4. A File Open dialo g bo x will be displayed. Cho o se the name o f the DLL file yo u
just c reated and c lic k o n the Open butto n to display the Install New Co mpo nents
dialo g bo x with the file yo u just selec ted (see Figure 18-8). If yo u need to install
mo re than o ne file, press the Add butto n.
5. After yo u have selec ted the files to be installed, c lic k Next to go to the last
step o f the wizard and press Finish to add the c o mpo nent to the applic atio n.
Figure 18-8: Selecting the nam e of your ActiveX DLL
Building a simple test program
In o rder to test the COM+ transac tio ns, I c reated simple IIS Applic atio n. This pro gram respo nds to the URL http://Athena/VB6DB18/VB6DB18.ASP with a Web
page, as sho wn in Figure 18-9.
Tip
IIS Applications are neat: My favorite feature in Visual Basic 6 is the ability to create a com piled, Web server-based application using IIS Applications. IIS
Applications are generally m ore efficient than ASP applications and they are m ore
secure because the source code is separate from the executable program .
When so meo ne enters the URL to run the IIS Applic atio n, IIS will trigger the
WebClass_Start event sho wn in Listing 18-8. Depending o n the request, o ne o f
three things will happen. If no fo rm info rmatio n is inc luded, a blank Web fo rm will be
displayed, with default values fo r the Customer o bjec t. If a GetCustomer request is
made, then the CustomerId value fro m the fo rm will be passed to the GetCustomer
transac tio n to retrieve the spec ified c usto mer. If a PutCustomer request is made,
then the info rmatio n o n the fo rm will be passed to the PutCustomer metho d to
update the database. A fo rm with the info rmatio n abo ut the c urrent c usto mer is
returned in bo th the PutCustomer and GetCustomer requests.
Chapter 18 ✦ Using COM + Transactions
Figure 18-9: View ing address inform ation returned by the COM+
transaction
Listing 18-8: The WebClass_Start event in Address
Information
Private Sub WebClass_Start()
Dim c As Cust.Customer
Dim ci As Object
If Len(Request.Form(“GetCustomer”)) > 0 Then
Set ci = CreateObject(“CustInfo.CustomerInfo”)
Set c = ci.GetCustomer(CLng(Request.Form(“CustomerId”)))
Set ci = Nothing
ElseIf Len(Request.Form(“PutCustomer”)) > 0 Then
Set ci = CreateObject(“CustInfo.CustomerInfo”)
Set c = New Cust.Customer
c.CustomerId = Request.Form(“CustomerId”)
c.Name = Request.Form(“Name”)
c.Street = Request.Form(“Street”)
c.City = Request.Form(“City”)
c.State = Request.Form(“State”)
c.Zip = Request.Form(“Zip”)
Continued
393
394
Part IV ✦ COM + Transactions, and M essage Queues
Listing 18-8 (continued)
c.Phone = Request.Form(“Phone”)
c.EMailAddress = Request.Form(“DateAdded”)
c.DateUpdated = Request.Form(“DateUpdated”)
If Request.Form(“MailingList”) = “ON” Then
c.MailingList = True
Else
c.MailingList = False
End If
c.Comments = Request.Form(“Comments”)
ci.PutCustomer c
Set ci = Nothing
Else
Set c = New Cust.Customer
c.CustomerId = 9999
End If
With Response
.Write “”
.Write “”
.Write “Address Information”
.Write “”
.Write “”
.Write “Address Information”
.Write “”
.Write “”
.Write “”
.Write “Customer Id:”
.Write “”
.Write “”
.Write “”
.Write “”
.Write “”
.Write “Name:”
.Write “”
.Write “”
.Write “”
.Write “”
.Write “”
.Write “Street:”
.Write “”
.Write “”
.Write “”
Chapter 18 ✦ Using COM + Transactions
.Write “”
.Write “”
.Write “City/State/Zip:”
.Write “”
.Write “”
.Write “”
.Write “”
.Write “”
.Write “”
.Write “”
.Write “Phone:”
.Write “”
.Write “”
.Write “”
.Write “”
.Write “”
.Write “Date Added/Date Updated:”
.Write “”
.Write “”
.Write “
C H A P T E R
Using COM +
Transactions
✦
✦
✦
✦
In This Cha pter
I
n this c hapter, I’ll sho w yo u ho w to c reate a COM+ transac tio n. These transac tio ns c an be used to implement an n-tier
applic atio n system, whic h c an o ffer signific ant perfo rmanc e
impro vements when c o mpared with mo re traditio nal c lient/
server applic atio ns.
A Brief Overview of COM +
Writing a COM+ pro gram isn’t diffic ult. If yo u understand ho w
to c reate and use a Class mo dule, then writing a COM+ transac tio n isn’t muc h mo re diffic ult than that. Ho wever, to write
an effec tive COM+ applic atio n means that yo u need to kno w
what COM+ is and ho w it wo rks.
M ulti-tier applications
In a traditio nal c lient/ server applic atio n, the c lient c o mputer
c o mmunic ates direc tly with the database server (see Figure
18-1). This is also kno wn as a 2-tier applic atio n pro gram.
Client Computer
Database Server
Figure 18-1: A 2-tier application
Reviewing the
CO M+ transactio n
architecture
Meeting the
ACID test
Co nstructing CO M+
transactio ns
Building a test
pro g ram
✦
✦
✦
✦
370
Part IV ✦ COM + Transactions, and M essage Queues
By using COM+ transac tio ns, yo u c an implement a 3-tier so lutio n. In prac tic e, yo u
have a c o mputer fo r the c lient, a sec o nd o ne fo r the COM+ transac tio n server, and a
third o ne fo r the database server (see Figure 18-2). No te that the transac tio n server
generally sits between the applic atio n c lient and the database server.
Client Computer
Transaction Server
Database Server
Figure 18-2: A 3-tier application
The transac tio n server is a plac e where yo u c an mo ve yo ur applic atio n lo gic away
fro m the c lient pro gram yet keep it independent o f the database server. This
allo ws mo re flexibility when designing yo ur applic atio n, bec ause yo u c an pro vide
an o bjec t-o riented view o f yo ur data, while making available fac ilities that allo w
yo u to share reso urc es fo r better perfo rmanc e and permit transac tio n suppo rt fo r
better reliability.
A mo re interesting so lutio n is sho wn in Figure 18-3. While I’ve labeled it a 4-tier pro c essing so lutio n, mo st peo ple c o nsider it just ano ther variatio n o f a 3-tier so lutio n,
bec ause they feel that the c lient c o mputer running a Web bro wser is no t a true tier.
Ho wever, given ho w easy it is to add VBSc ript o r JavaSc ript to the Web page to perfo rm basic func tio ns like data validatio n, why no t c o nsider it a true tier?
In general, yo u c an refer to multi-tier so lutio ns as n-tier, where n refers to the number o f levels o f c o mputers used in the applic atio n design. No te that I do n’t simply
c o unt the number o f c o mputers, bec ause it is quite po ssible to have mo re than o ne
Web server, mo re than o ne transac tio n server o r mo re than o ne database server
that pro vides the same basic servic es, but are implemented o n multiple c o mputers
to better handle the wo rklo ad. With n-tier so lutio ns, eac h level o f c o mputers pro vides a new type o f servic e. In prac tic e, ho wever, eac h new level o f c o mputers intro duc es additio nal o verhead and beyo nd the fo ur c o mputers sho wn in Figure 18-3, it is
do ubtful that yo u wo uld gain any additio nal benefit fro m adding a new tier.
Chapter 18 ✦ Using COM + Transactions
Client Computer
Web Server
Transaction Server
Database Server
Figure 18-3: A 4-tier application
Transaction Servers
The transac tio n server rec eives requests fro m the pro gram running o n the c lient
and starts a transac tio n to pro c ess it. If info rmatio n is needed fro m the database
server, the transac tio n will c o mmunic ate with the database server. When the
transac tio n has finished pro c essing, it will return bac k to the c alling pro gram.
Adding the third tier, yo u o fflo ad so me o f the wo rk fro m the database server, whic h
allo ws the database server to perfo rm additio nal wo rk o n the same hardware c o nfiguratio n. It also simplifies updating the applic atio n, sinc e it is po ssible to make
c hanges to a transac tio n o n the transac tio n server witho ut c hanging the c lient pro gram that c alls the transac tio n.
In a 4-tier so lutio n, using a transac tio n server makes even mo re sense. It allo ws yo u
to o fflo ad wo rk fro m bo th the Web server and the database server o nto a separate
c o mputer system, whic h serves to impro ve respo nse time o n bo th mac hines. This
allo ws yo u to inc rease the available memo ry fo r Web page c ac hing and database
rec o rd c ac hing.
371
372
Part IV ✦ COM + Transactions, and M essage Queues
Typic ally, the database server, transac tio n server, and Web server (if present) are
all c o nnec ted via a very high-speed c o nnec tio n. At least a 100 MHz Ethernet, if no t
a gigahertz Ethernet o r o ther spec ialized netwo rking tec hno lo gy, is used to c o nnec t
these c o mputers to gether. Often this netwo rk is iso lated fro m the o ther netwo rks
to impro ve sec urity and perfo rmanc e. This means that there are very few delays
c aused by the netwo rk. Yet by spreading the wo rk aro und, yo u c an ensure that no
o ne system is o verlo aded. Yo u c an even add additio nal Web servers and transac tio n servers transparently if yo u really need them witho ut requiring c hanges to
yo ur applic atio n.
COM + applications
A COM+ transac tio n is basic ally a COM o bjec t that has been c o ded and c o mpiled
to run under the COM+ transac tio n server. In Visual Basic , yo u c reate a COM+ transac tio n by building an Ac tiveX DLL applic atio n. Yo u need to inc lude a few spec ial
o bjec ts and add a little c o de to perfo rm so me handshaking with the transac tio n
server and use a spec ial to o l to define yo ur transac tio n to the transac tio n server.
But o ther than that, yo u’re free to take advantage o f the Visual Basic language.
A COM+ applic atio n is just a c o llec tio n o f o ne o r mo re COM+ transac tio ns that are
gro uped to gether into a single Ac tiveX DLL file. There are fo ur basic types o f COM+
applic atio ns:
✦ Server applications: A server applic atio n is the mo re c o mmo n fo rm o f a
COM+ applic atio n. It runs under c o ntro l o f the transac tio n server. The applic atio n c an interac t with the transac tio n server thro ugh the o bjec ts asso c iated
with the transac tio n’s c o ntext.
✦ Library applications: A library applic atio n is a spec ialized fo rm o f a COM+
applic atio n that runs lo c ally o n the c lient c o mputer. It runs in the same
address spac e as the c lient pro gram that c reated it. This means less o verhead
to the c lient pro gram, bec ause several COM+ applic atio ns c an use the same
c o mpo nents. Ho wever, bec ause this o bjec t isn’t running under the c o ntro l o f
the transac tio n server, it c an’t take advantage o f so me o f the features o f the
transac tio n server.
✦ Application proxies: An applic atio n pro xy c o ntains the registratio n info rmatio n nec essary fo r an applic atio n to remo tely ac c ess a server applic atio n. If
yo u run it o n the c lient c o mputer, all o f the info rmatio n nec essary to ac c ess
a spec ific remo te server applic atio n will be installed o n the c lient c o mputer.
✦ COM+ preinstalled applications: COM+ c o mes with a set o f applic atio ns that
help yo u c o nfigure and administer yo ur COM+ system. These applic atio ns
inc lude COM+ System Administratio n, COM+ Utilities, and IIS System
Applic atio ns.
Of these types o f COM+ applic atio ns, I’m go ing to fo c us o n server applic atio ns,
sinc e they are the mo st useful o f all.
Chapter 18 ✦ Using COM + Transactions
The COM + transaction server
The COM+ Transac tio n Server pro vides a framewo rk to exec ute transac tio ns o n an
n-tier applic atio n system. Inc luded with the Server are fac ilities that allo w yo u to
share reso urc es, suc h as ASO Connection o bjec ts, and pro vide additio nal sec urity
o n yo ur transac tio n.
Yo u c an o nly run the COM+ Transac tio n Server under Windo ws 2000 Server. Yo u
c an’t run it under Windo ws 9x, Windo ws NT, o r even Windo ws 2000 Pro fessio nal. It
relies o n fac ilities, suc h as the Ac tive Direc to ry, to manage muc h o f the info rmatio n
it needs to run yo ur transac tio ns. Bec ause the COM+ Transac tio n Server represents
o nly o ne tier in an applic atio n, yo u c an use any database server yo u c ho o se, even if
it runs under a different o perating system suc h as Unix. The o nly restric tio n is that
the database server must be suppo rted by ADO.
Note
Serving transactions under Windows NT: If you w ant to run transactions under
Window s NT Server, you need to use a tool called Microsoft Transaction Server,
usually called MTS. Many of the basic facilities in MTS w ere upgraded to create
COM+ , but COM+ is not upw ards com patible w ith MTS. COM+ requires less code
to interact w ith the transaction server and is easier to adm inister than MTS.
The object context
Every COM+ transac tio n that is run under c o ntro l o f the COM+ Transac tio n Server
is asso c iated with a set o f o bjec ts kno wn as a co nte xt. A c o ntext represents the
smallest po ssible unit o f wo rk fo r a c o mpo nent. Eac h instanc e o f a COM o bjec t is
assigned to a c o ntext. Multiple o bjec ts c an use the same c o ntext depending o n ho w
they were defined and c reated.
The o bjec t c o ntext c o ntains info rmatio n abo ut ho w the o bjec t was c reated and the
status o f the wo rk that is c urrently ac tive. Yo u c an ac c ess these fac ilities thro ugh
the ObjectContext o bjec t. All o f the o ther o bjec ts in the c o ntext c an be referenc ed
fro m this o bjec t either direc tly o r indirec tly.
The Component Services utility
The Co mpo nent Servic es utility is used to manage and c o nfigure COM+ transac tio ns (see Figure 18-4). Yo u c an start it in Windo ws 2000 by c ho o sing Pro grams ➪
Administrative To o ls ➪ Co mpo nent Servic es fro m the Start butto n. This to o l will be
used frequently while testing yo ur applic atio n to c hange the c harac teristic s o f the
transac tio n, as well as to install updated c o pies o f the COM c o mpo nent that makes
up yo ur COM+ applic atio n.
373
374
Part IV ✦ COM + Transactions, and M essage Queues
Figure 18-4: Running the Com ponent Services utility
Introducing COM + Transactions
COM+ transac tio ns are a feature o f Windo ws 2000 that yo u c an use when building
sc alable, n-tier applic atio ns. COM+ is built o n to p o f COM and integrates features
suc h as the Mic ro so ft Transac tio n Server and Mic ro so ft Message Queues into a
single tec hno lo gy.
COM+ is built using C++ and so me o f its features c an o nly be ac c essed fro m C++.
Ho wever, this do esn’t mean that yo u c an’t use COM+ fro m Visual Basic 6. In fac t,
many o f the features are ac tually very easy to use, o nc e yo u understand ho w to
wo rk with them. Bec ause this bo o k is aimed at Visual Basic pro grammers, I’ll fo c us
o n the features yo u c an explo it to day and leave the rest fo r the C++ pro grammers.
Note
A view of things to come: As I w rite this, there are m any rum ors surrounding
the features that w ill be present in Visual Basic 7. While it isn’t clear exactly w hat
features w ill be present, you can bet that support for COM+ w ill be at the top of
the list.
In Chapter 16, I talked abo ut ho w to use the BeginTransaction, CommitTransaction,
and RollbackTransaction metho ds to define a transac tio n o ver a database c o nnec tio n. These transac tio ns represented a fundamental unit o f wo rk fo r the applic atio n.
Chapter 18 ✦ Using COM + Transactions
They c o uld c o ntain the database c alls nec essary to make a withdrawal fro m yo ur
savings ac c o unt, register yo u fo r a c o llege c o urse, o r even o rder a bo o k o ver the
Internet.
Simply lo o king at a transac tio n fro m a database perspec tive may be a bit to o limiting
fo r many applic atio ns. In additio n to manipulating data in the database, transac tio ns
o ften perfo rm validatio n alo ng with the database ac tivities. Fo r example, befo re making a withdrawal fro m yo ur c hec king ac c o unt, yo u must first verify that the ac c o unt
number is valid, and sec o nd, that there are suffic ient funds in the c hec king ac c o unt
befo re subtrac ting the mo ney fro m that ac c o unt.
There are a several ways to implement a transac tio n. The mo st c o mmo n way is to
write c o mplex sto red pro c edures that run o n the database server. This appro ac h
impo ses extra wo rk o n the database server, whic h may detrac t fro m the database
server’s o verall perfo rmanc e. In Windo ws 2000, yo u have the o ptio n o f building
COM+ transac tio ns that run under c o ntro l o f a transac tio n server, whic h yo u c an
easily run o n a separate mac hine.
The ACID test
Eac h COM+ transac tio n must meet the ACID test. The letters in ACID stand fo r
Ato mic ity, Co nsistenc y, Iso latio n, and Durab ility, and serve to identify the different c riteria that a transac tio n must meet.
Atomicity
Ato micity means that either all o r no ne o f a transac tio n is c o mpleted. In o ther wo rds,
the wo rk a transac tio n perfo rms c an’t be subdivided. If the transac tio n c o mpletes
suc c essfully, all o f the c hanges it makes will remain. If the transac tio n fails, then all
o f the c hanges it made must be undo ne.
Co nsider an airline reservatio ns system. When yo u make a reservatio n, yo u spec ify
the date, flight number, number o f seats yo u want, plus a number o f parameters
suc h as first c lass o r ec o no my. Yo u want the reservatio n to suc c eed o nly if all o f
these parameters are met. Otherwise yo u want the reservatio n to fail, so yo u c an
try again. Either all o f the seats yo u requested are available o r no ne o f them.
Consistency
Ano ther aspec t o f a transac tio n is that it must always leave the system in a c o nsistent state. Co nsider what happens if yo u mo ve mo ney fro m yo ur savings ac c o unt
to yo ur c hec king ac c o unt. Yo u have to read the c urrent balanc e fro m the savings
ac c o unt, subtrac t the amo unt o f mo ney yo u want to mo ve, and update the ac c o unt
with the new balanc e. Then yo u have to read the c urrent balanc e fro m the c hec king
ac c o unt, add the mo ney to it, and update the ac c o unt with the new balanc e.
375
376
Part IV ✦ COM + Transactions, and M essage Queues
Co nsider what happens if the pro c ess fails after the first update is finished, but
befo re the sec o nd update is made. The database will auto matic ally ensure that the
first update is saved, but it will no t save an inc o mplete update. This means that the
mo ney wo uld be remo ved fro m yo ur saving ac c o unt but no t added to yo ur c hec king ac c o unt. Fo r all prac tic al purpo ses, the mo ney wo uld be lo st and the database
left in an inc o nsistent state.
By plac ing the two updates into a transac tio n, yo u c an ensure that the database is
left in a c o nsistent state. Either bo th updates are c o mpleted o r bo th updates are
no t c o mpleted. In this example, whether the transac tio n suc c eeds o r fails, the
mo ney wo n’t be lo st.
Isolation
While no t as o bvio us as the previo us c harac teristic s o f a transac tio n, iso latio n is
also very impo rtant. Eac h transac tio n lives in its o wn wo rld, where it c an’t see any
o f the pro c essing perfo rmed by ano ther ac tive transac tio n. The c o nc ept o f iso latio n
is impo rtant bec ause it allo ws the system to rec o ver fro m failures. While the system
is ac tively pro c essing transac tio ns, yo u may have do zens o r even hundreds o f
ac tive transac tio ns at any po int in time. Ho wever, with transac tio n iso latio n, these
transac tio ns c an be viewed as a single stream o f transac tio ns, where o ne transac tio n is c o mpleted befo re the next o ne begins. This pro c ess allo ws rec o very pro grams to wo rk, and makes it po ssible to implement distributed database systems.
Durability
The last c harac teristic o f a transac tio n is its ability to survive system failures. Onc e
a transac tio n has been c o mpleted, it is c ritic al that the c hanges it made aren’t lo st.
Fo r this reaso n, it’s impo rtant that the system keep lo gs and bac kups o f all the transac tio ns that were pro c essed. These files make it po ssible fo r wo rk to be rec o vered in
c ase o f a c atastro phic system failure.
Class module properties for transactions
In o rder to identify a Visual Basic c lass mo dule as a COM+ transac tio n, yo u need to
adjust so me o f its pro perties. These pro perties c o ntro l ho w Visual Basic will c o mpile yo ur pro gram.
In o rder to run a transac tio n under c o ntro l o f COM+ yo u need to spec ify the value
o f the MTSTransactionMode pro perty in the c lass mo dule. While this value c an be
o verridden by the Co mpo nent Servic es utility, yo u sho uld c ho o se the pro per value
befo re yo u try to install it under COM+. Table 18-1 lists the Visual Basic c o nstant
that yo u c an set using the Pro perties windo w fo r the c lass mo dule.
Chapter 18 ✦ Using COM + Transactions
Table 18-1
M TSTransactionM ode Values
Visual Basic Constant
COM + Transaction Support
Numeric Value
NotAnMTSObject
Disabled
0
NoTransactions
Not Supported
1
RequiresTransaction
Required
2
UsesTransaction
Supported
3
RequiresNewTransaction
Requires New
4
✦ NotAnMTSObje ct implies that the o b jec t isn’t suppo rted under COM+
Transac tio n Server. Yo u sho uld use this value when yo u do no t expec t to
run yo ur c o mpo nent under c o ntro l o f the Transac tio n Server.
✦ NoTransactions means that the o bjec t do esn’t suppo rt transac tio ns. When a
new instanc e o f the o bjec t is c reated, its o bjec t c o ntext is c reated witho ut a
transac tio n.
✦ RequiresTransaction means that the c o mpo nent’s o bjec ts must exec ute witho ut the sc o pe o f a transac tio n. When a new instanc e o f the o bjec t is c reated,
the o bjec t c o ntext is inherited fro m the o bjec t c o ntext o f the c lient. If the
c lient do esn’t have a transac tio n, a new transac tio n is c reated fo r the o bjec t.
If the c lient is a COM+ transac tio n, then a new transac tio n will no t be started
bec ause o ne is already ac tive.
✦ UsesTransaction means that the c o mpo nent’s o bjec ts c an exec ute within the
sc o pe o f a transac tio n. When a new instanc e o f the o bjec t is c reated, its o bjec t
c o ntext is inherited fro m the o bjec t c o ntext o f the c lient. If the c lient do esn’t
have a transac tio n, the new o bjec t will run witho ut a transac tio n.
✦ RequiresNewTransaction means that the c o mpo nent’s o bjec ts must exec ute
within their o wn transac tio ns. When a new instanc e o f the o bjec t is c reated, a
new transac tio n will auto matic ally be c reated fo r the o bjec t, even if the c alling
o bjec t is already exec uting within a transac tio n.
The ObjectContext object
The ObjectContext o bjec t is the mo st impo rtant o bjec t when implementing a
COM+ transac tio n. Thro ugh this o bjec t, yo u will c o ntro l ho w the transac tio n
behaves. Yo u c an use this o bjec t to c o mmunic ate with the transac tio n server and
find o ut info rmatio n abo ut the enviro nment in whic h it is running.
377
378
Part IV ✦ COM + Transactions, and M essage Queues
Yo u c an get ac c ess to this o bjec t by selec ting the COM+ Servic es Type Library
fro m the Referenc es windo w by c ho o sing Pro jec t ÿ Referenc es fro m the Visual
Basic main menu ( see Figure 18-5) and then dec laring and c alling the
GetObjectContext func tio n, as sho wn belo w:
Dim MyContext As ObjectContext
Set MyContext = GetObjectContext()
Figure 18-5: Selecting the COM+
Services Type Library
ObjectContext object properties
Table 18-2 lists the pro perties o f the ObjectContext o bjec t.
Table 18-2
Properties of the ObjectContext Object
Property
Description
ContextInfo
An object reference to the ContextInfo object.
Count
A Long value containing the num ber of property objects.
Item
An object reference to a specific property object.
Security
An object reference to the SecurityProperty object.
ObjectContext object methods
Of the metho ds available fo r the ObjectContext o bjec t, the mo st impo rtant are
SetAbort and SetComplete. These instruc t the transac tio n server whether to
allo w the transac tio n’s ac tivities to be saved o r undo ne.
Chapter 18 ✦ Using COM + Transactions
Function CreateInstance (bstrProgID As String) As Variant
The CreateInstance metho d returns an o b jec t referenc e to a new instanc e o f
the spec ified o b jec t using the c urrent o b jec t’s c o ntext. This func tio n sho uld b e
used in plac e o f the CreateObject func tio n, b ec ause it implements the c urrent
c o ntext fo r its exec utio n. If the o b jec t isn’t registered with COM+, the o b jec t is
merely c reated and no c o ntext will b e assigned. If the o b jec t is registered with
COM+, it will b e c reated ac c o rding to the COM+ Transac tio n Suppo rt value and
the MTSTransactionMode pro perty. bstrProgID is a String value c o ntaining
the name o f the o b jec t to b e c reated.
Sub DisableCommit( )
The DisableCommit metho d tells the transac tio n server that the o bjec t’s wo rk has
left the system in an inc o nsistent state.
Sub EnableCommit( )
The EnableCommit metho d tells the transac tio n server that the o bjec t’s wo rk may
no t be c o mplete, but that the system is no w in a c o nsistent state.
Function IsCallerInRole(bstrRole As String) As Boolean
The IsCallerInRole metho d returns True when the o bjec t’s direc t c aller is in the
spec ified ro le, either individually o r as part o f a gro up. bstrRole is a String value
c o ntaining the sec urity ro le.
Function IsInTransaction( ) As Boolean
The IsInTransaction metho d is True when the o bjec t is exec uting inside a transac tio n.
Function IsSecurityEnabled ( ) As Boolean
The IsSecurityEnabled metho d is True when sec urity is enabled.
Sub SetAbort( )
The SetAbort metho d instruc ts the transac tio n server to undo any o f the transac tio n’s ac tio ns. This may be bec ause an unrec o verable erro r has o c c urred o r the system is in an inc o nsistent state.
Sub SetComplete( )
The SetComplete metho d instruc ts the transac tio n server to c o mmit all updates to
the system bec ause the transac tio n has c o mpleted its wo rk suc c essfully.
379
380
Part IV ✦ COM + Transactions, and M essage Queues
Constructing a COM + Transaction
Co nstruc ting a COM+ transac tio n is fairly easy. Yo u start by c reating an Ac tiveX DLL
pro jec t to ho ld the transac tio n. If yo u want to pass any o bjec ts between the transac tio n and the pro gram, yo u will need a sec o nd Ac tiveX DLL to ho ld the type info rmatio n. Finally, to test yo ur transac tio n, yo u’ll need a simple applic atio n that c alls
the transac tio n.
Fo r this example, I’m go ing to use the Custo mers table and c reate COM+ transac tio ns to retrieve a single c usto mer and to update a single c usto mer. The info rmatio n will be passed bac k and fo rth between the c lient and the transac tio n server
using the Custo mer o bjec t. To demo nstrate the transac tio ns, I’m also go ing to
build a simple IIS Applic atio n and run it thro ugh the IIS Web server.
Holding type information
One pro blem yo u will enc o unter when yo u begin using COM+ transac tio ns is that
yo u c an’t rely o n glo bal variables to pass info rmatio n bac k and fo rth to the ro utines
yo u may c all. Everything must be passed as a parameter. Depending o n the data
yo u want to share with a ro utine, this c an be a pro blem.
Using Visual Basic ’s c lass mo dules, yo u c an c reate an o bjec t that c o ntains a lo t o f
info rmatio n in a single entity. When using so me o f the mo re advanc ed features in
Windo ws, suc h as COM+ transac tio ns and message queuing, this is my favo rite way
to pass info rmatio n aro und.
The do wnside to using c lass mo dules to pass info rmatio n aro und in a COM+ transac tio n is that yo u really have to deal with two different pro grams. The COM+ transac tio n o perates independently o f the applic atio n pro gram using the transac tio n.
Therefo re, bo th pro grams need a c o py o f the definitio ns. The o nly reaso nable way
to handle this situatio n is to intro duc e a third c o de mo dule that ho lds the type definitio ns fo r yo ur transac tio ns. This third mo dule exists o n bo th the c lient mac hine
and the transac tio n server mac hine.
Creating storage for property values
Like any o b jec t, the Custo mer o b jec t c o nsists o f a series o f Public Property
Get and Property Let ro utines, whic h are used to ac c ess a b unc h o f Private
variab les defined at the mo dule level. Listing 18-1 c o ntains the list o f Private
variab les. No te that eac h o f the variab le names b egins with an X. This is b ec ause I
wanted the o b jec t’s user to see the field names I used in the datab ase rather than
use a c ryptic ab b reviatio n. Sinc e I’m the o nly perso n who expec ts to see inside
the Custo mer o b jec t, I do n’t c o nsider this a real hardship.
Chapter 18 ✦ Using COM + Transactions
Listing 18-1: The module level declarations in Customer
Option Explicit
Private
Private
Private
Private
Private
Private
Private
Private
Private
Private
Private
Private
Private
XCustomerID As Long
XName As String
XStreet As String
XCity As String
XState As String
XZip As Long
XPhone As String
XEMailAddress As String
XDateAdded As Date
XDateUpdated As Date
XMailingList As Boolean
XComments As String
XIsDirty As Boolean
Yo u sho uld no te that in additio n to the vario us fields fro m the database, I also
added o ne mo re value, c alled XIsDirty. The XIsDirty pro perty is used to indic ate
when the data in the o bjec t has been c hanged. It’s a quic k and easy way to determine if the info rmatio n was c hanged and the database sho uld be updated.
M anaging property values
The Property Get ro utine just returns the value o f the c o rrespo nding X variable
(see Listing 18-2), while the Property Let ro utine is a little mo re c o mplic ated (see
Listing 18-3).
The Property Let ro utine determines if the value o f the pro perty is different than
the value already in private sto rage. If the value is different, then I save the new value,
set the XIsDirty pro perty, and mark the pro perty as c hanged. Otherwise, I igno re
the assignment. While c hec king the assignment is a little extra wo rk, it allo ws so meo ne to reassign the c urrent value to the pro perty witho ut resetting the XIsDirty flag.
Listing 18-2: The CustomerId Property Get
routine in Customer
Public Property Get CustomerId() As Long
CustomerId = XCustomerID
End Property
381
382
Part IV ✦ COM + Transactions, and M essage Queues
Listing 18-3: The CustomerId Property Let
routine in Customer
Public Property Let CustomerId(c As Long)
If c XCustomerID Then
XCustomerID = c
XIsDirty = True
PropertyChanged “CustomerId”
End If
End Property
Note
Property M ay I: The CanPropertyChange m ethod isn’t required w hen dealing
w ith properties in the Customer object, since the Customer object can’t act as a
data consum er.
Initializing property values
I c ho se to make the Custo mers o bjec t a persistable o bjec t. This will have a big benefit later when I talk abo ut message queuing in Chapter 19. Ho wever, fo r no rmal
COM+ transac tio ns, yo u do n’t really need persistent o bjec ts. Onc e the o bjec t is
instantiated, it will remain instantiated until yo u destro y it.
Listing 18-4 c o ntains the statements nec essary to initialize the variables in lo c al
sto rage. No te that I just use reaso nable default values fo r all o f these pro perties
exc ept fo r XDateAdded and XDateUpdated. Fo r these values, I use the func tio n Now
to save the c urrent date and time into these variables. This makes it easier fo r
so meo ne to c reate a new Custo mer o bjec t and no t wo rry abo ut assigning values to
these two fields. It also wo n’t c ause a pro blem when the COM+ transac tio n returns
info rmatio n fro m the database, sinc e these initial values will be o verlaid with the
live values fro m the database.
Listing 18-4: The Class_InitProperties event in Customer
Private Sub Class_InitProperties()
XCustomerID = -1
XName = “”
XStreet = “”
XCity = “”
XState = “”
Chapter 18 ✦ Using COM + Transactions
XZip = 0
XPhone = “”
XEMailAddress = “”
XDateAdded = Now
XDateUpdated = Now
XMailingList = False
XComments = “”
XIsDirty = False
End Sub
As yo u wo uld expec t, the ReadProperties and WriteProperties events are pretty
simple, just a series o f statement that use the ReadProperty and WriteProperty
metho ds to resto re and save these values. Listing 18-5 sho ws the ReadProperties
event.
Listing 18-5: The Class_ReadProperties event in Customer
Private Sub Class_ReadProperties(PropBag As PropertyBag)
XCustomerID = PropBag.ReadProperty(“CustomerId”, 0)
XName = PropBag.ReadProperty(“Name”, “”)
XStreet = PropBag.ReadProperty(“Street”, “”)
XCity = PropBag.ReadProperty(“City”, “”)
XState = PropBag.ReadProperty(“State”, “”)
XZip = PropBag.ReadProperty(“Zip”, 0)
XPhone = PropBag.ReadProperty(“Phone”, “”)
XEMailAddress = PropBag.ReadProperty(“EMailAddress”, “”)
XDateAdded = PropBag.ReadProperty(“DateAdded”, 0)
XDateUpdated = PropBag.ReadProperty(“DateUpdated”, 0)
XMailingList = PropBag.ReadProperty(“MailingList”, False)
XComments = PropBag.ReadProperty(“Comments”, “”)
XIsDirty = False
End Sub
No te that even tho ugh I assign the c urrent date and time in the InitProperties
event to the DateAdded and DateUpdated pro perties, I use a default value o f
zero . This just means that these pro perties will always b e sto red in the pro perty
b ag, whic h is likely to happen anyway, given the nature o f the data sto red in the
pro perties.
383
384
Part IV ✦ COM + Transactions, and M essage Queues
Installing the DLL
Onc e yo u build yo ur pro gram, yo u need to c o mpile it to an Ac tiveX DLL (Dynamic
Linking Library) and then register it in the Windo ws Registry. When yo u register
yo ur DLL, selec ted info rmatio n abo ut the DLL will be lo aded into the Registry,
inc luding the lo c atio n o f the DLL file, the name o f the o bjec ts available, and the
Glo bally Unique Identifiers (GUID) that are used to lo c ate them.
When yo ur pro gram referenc es an o bjec t, it presents the o bjec t’s GUID to Windo ws,
whic h in turn uses it as a key to lo c ate info rmatio n abo ut the o bjec t in the Registry.
This means that the ac tual lo c atio n o f the file c an be independent o f the applic atio n.
To register yo ur file, yo u need to use the RegSvr32 utility pro gram. To run it, c ho o se
Start ➪ Run fro m the Windo ws taskbar. Then enter the RegSvr32 fo llo wed by the
fully qualified path name to the DLL file, as sho wn belo w:
RegSvr32 d:\VB6DB\Chapter18\CustomerObjects\cust.dll
and press Enter. The registratio n pro gram will run fo r a split sec o nd and display a
message bo x saying that RegisterDLL Server suc c eeded.
If yo u need to make a c hange to the DLL after yo u have registered it, yo u must run
the fo llo wing c o mmand:
RegSvr32 /u d:\VB6DB\Chapter18\CustomerObjects\cust.dll
It will ac kno wledge the request by saying DLLUnregister Server suc c eeded.
Tip
DOS ain’t dead: After using DOS and m any other character operating system s
over the years, I actually like typing m y com m ands and seeing the results. I often
use DOS to display directory inform ation and to copy files, and as a result, I usually have a DOS w indow open. So rather than choosing Start ➪ Run, I usually just
toggle to m y DOS w indow to run the RegSvr32 com m and. Besides, if the DLL is in
the current directory, I need only type the file nam e rather than the fully qualified
path nam e.
Accessing the database with transactions
No w that I have an o bjec t I c an pass bac k and fo rth to COM+ transac tio ns, I want to
build so me transac tio ns. Fo r all prac tic al purpo ses, building a COM+ transac tio n is
just like building any o ther COM c o mpo nent that ac c esses a database — with two
exc eptio ns. First, yo u need to use the ObjectContext o bjec t to info rm the transac tio n server o f the transac tio n’s status. Sec o nd, yo u need to grab and release
database reso urc es, suc h as the Co nnec tio n o bjec t, quic kly.
Chapter 18 ✦ Using COM + Transactions
Getting customer information
The GetCustomer metho d (see Listing 18-6) retrieves the c usto mer info rmatio n fo r
the c usto mer spec ified in the CustomerId parameter and returns it to the c alling
pro gram using the Custo mer o bjec t. While a metho d that stric tly reads info rmatio n
fro m the database do esn’t benefit fro m the COM+ transac tio n server’s ability to
manage c o mplex transac tio ns, it do es allo w this ro utine to o perate mo re effic iently
than it wo uld if yo u embedded the c o de direc tly in yo ur applic atio n pro gram.
Listing 18-6: The GetCustomer method of CustomerInfo
Public Function GetCustomer(CustomerId As Long) As Customer
Dim
Dim
Dim
Dim
Dim
Dim
c As Customer
cmd As ADODB.Command
db As ADODB.Connection
o As ObjectContext
parm As ADODB.Parameter
rs As ADODB.Recordset
Set o = GetObjectContext()
Err.Clear
Set db = New ADODB.Connection
db.Provider = “sqloledb”
db.ConnectionString = “Athena”
db.CursorLocation = adUseNone
db.Open , “sa”, “”
db.DefaultDatabase = “VB6DB”
Set cmd = New ADODB.Command
Set cmd.ActiveConnection = db
cmd.CommandText = “Select * from Customers “ & _
“Where CustomerId = ?”
Set parm = cmd.CreateParameter(“CustomerId”, adInteger, _
adParamInput, 4)
cmd.Parameters.Append parm
Err.Clear
cmd.Parameters(“CustomerId”).Value = CustomerId
Set rs = cmd.Execute
If Err.Number 0 Then
App.LogEvent “CustomerInfo(GetCustomer): “ & _
“Can’t retrieve the “ & _
“record for CustomerId “ & _
FormatNumber(CustomerId, 0) & “. Error: “ & _
Err.Description & “-” & _
Hex(Err.Number)
Continued
385
386
Part IV ✦ COM + Transactions, and M essage Queues
Listing 18-6 (continued)
Set c = Nothing
Else
Set c = New Customer
c.CustomerId = rs.Fields(“CustomerId”)
c.Name = rs.Fields(“Name”)
c.Street = rs.Fields(“Street”)
c.City = rs.Fields(“City”)
c.State = rs.Fields(“State”)
c.Zip = rs.Fields(“Zip”)
c.Phone = rs.Fields(“Phone”)
c.EMailAddress = rs.Fields(“EMailAddress”)
c.DateAdded = rs.Fields(“DateAdded”)
c.DateUpdated = rs.Fields(“DateUpdated”)
c.MailingList = rs.Fields(“MailingList”)
c.Comments = rs.Fields(“Comments”)
End If
Set GetCustomer = c
rs.Close
db.Close
Set rs = Nothing
Set db = Nothing
Set c = Nothing
Set o = Nothing
End Function
The GetCustomer metho d begins by dec laring a number o f o bjec ts that I’ll use in
this pro gram. Next, I’ll get an o bjec t referenc e to the ObjectContext fo r this transac tio n. While I do n’t really need it, it isn’t a bad idea to get in the habit o f starting
every metho d by getting the c o ntext.
Next, I establish a c o nnec tio n to the database. Rather than c reating a c o nnec tio n
o nc e and using it fo r all transac tio ns that this o bjec t might exec ute, it is mo re effic ient to get a c o nnec tio n, use it, and then release it as quic kly as po ssible. The
COM+ transac tio n server interc epts yo ur c all and satisfies yo ur request with an
existing c o nnec tio n fro m a po o l o f c o nnec tio ns it maintains. When yo u release the
c o nnec tio n, the COM+ transac tio n server adds it bac k to the po o l and makes it available fo r so meo ne else to use. By sharing c o nnec tio ns in this fashio n, bo th yo ur
applic atio n and the database server have a lo t less wo rk to do .
Chapter 18 ✦ Using COM + Transactions
After the c o nnec tio n is o pened, I c reate a Command o bjec t with a parameterized
Select statement and its asso c iated Parameter o bjec t. I c ho se to use the Command
o bjec t rather than a Recordset bec ause the Command o bjec t will be mo re effic ient
in the lo ng run. SQL Server 7 will parse the query the first time it sees it, and the
next time I use the query, it will be able to use the already parsed versio n. This
makes it nearly as fast as a sto red pro c edure, witho ut the headac hes o f c reating a
sto red pro c edure.
When I exec ute the Command, it will return a Recordset o bjec t c o ntaining the
value I requested, in whic h c ase I’ll save the values into a Customer o bjec t and
return it as the value o f the func tio n. If exec uting the Command generated an erro r,
I’ll write the erro r to the applic atio n’s lo g file and return Nothing as the value o f
the func tio n.
At the end o f the func tio n, I c lo se the Recordset and Connection o bjec ts and destro y
all o f the o bjec ts I used in the ro utine. No te that I destro y the ObjectContext o bjec t,
sinc e it is no lo nger nec essary. A c all to SetComplete o r SetAbort isn’t nec essary
sinc e I didn’t mo dify any data.
Saving customer information
The PutCustomer metho d sho wn in Listing 18-7 fo llo ws the same basic lo gic flo w
as the GetCustomer metho d yo u saw in 18-6. I begin by ac quiring a c o nnec tio n to
the database. Then I c reate a Command o bjec t that exec utes an SQL Update statement. Next I assign the appro priate values fro m the Customer o bjec t to the parameters in the c o mmand and then exec ute the Update statement. Finally, I return any
erro r info rmatio n as the value o f the func tio n, signal the ObjectContext that the
transac tio n is c o mplete and destro y the o bjec ts I used.
Listing 18-7: The PutCustomer method of CustomerInfo
Public Function PutCustomer(c As Customer) As Long
On Error Resume Next
Dim
Dim
Dim
Dim
cmd As ADODB.Command
db As ADODB.Connection
o As ObjectContext
parm As ADODB.Parameter
Set o = GetObjectContext()
PutCustomer = 0
Err.Clear
Continued
387
388
Part IV ✦ COM + Transactions, and M essage Queues
Listing 18-7 (continued)
Set db = New ADODB.Connection
db.Provider = “sqloledb”
db.ConnectionString = “Athena”
db.CursorLocation = adUseNone
db.Open , “sa”, “”
db.DefaultDatabase = “VB6DB”
Set cmd = New ADODB.Command
Set cmd.ActiveConnection = db
cmd.CommandText = “Update Customers Set Name=?, Street=?, “ _
“City=?, State=?, “ & _
“Zip=?, Phone=?, EMailAddress=?, DateAdded=?, “ & _
“DateUpdated=?, MailingList=?, Comments=? “ & _
“Where CustomerId=?”
Set parm = cmd.CreateParameter(“Name”, adVarChar, _
adParamInput, 64)
cmd.Parameters.Append parm
Set parm = cmd.CreateParameter(“Street”, adVarChar, _
adParamInput, 64)
cmd.Parameters.Append parm
Set parm = cmd.CreateParameter(“City”, adVarChar, _
adParamInput, 64)
cmd.Parameters.Append parm
Set parm = cmd.CreateParameter(“State”, adChar, _
adParamInput, 2)
cmd.Parameters.Append parm
Set parm = cmd.CreateParameter(“Zip”, adInteger, _
adParamInput, 4)
cmd.Parameters.Append parm
Set parm = cmd.CreateParameter(“Phone”, adVarChar, _
adParamInput, 32)
cmd.Parameters.Append parm
Set parm = cmd.CreateParameter(“EMailAddress”, adVarChar, _
adParamInput, 128)
cmd.Parameters.Append parm
Set parm = cmd.CreateParameter(“DateAdded”, adDBDate, _
adParamInput)
cmd.Parameters.Append parm
Chapter 18 ✦ Using COM + Transactions
Set parm = cmd.CreateParameter(“DateUpdated”, adDBDate, _
adParamInput)
cmd.Parameters.Append parm
Set parm = cmd.CreateParameter(“MailingList”, adBoolean, _
adParamInput)
cmd.Parameters.Append parm
Set parm = cmd.CreateParameter(“Comments”, adVarChar, _
adParamInput, 256)
cmd.Parameters.Append parm
Set parm = cmd.CreateParameter(“CustomerId”, adInteger, _
adParamInput, 4)
cmd.Parameters.Append parm
cmd.Parameters(“CustomerId”).Value = c.CustomerId
cmd.Parameters(“Name”).Value = c.Name
cmd.Parameters(“Street”).Value = c.Street
cmd.Parameters(“City”).Value = c.City
cmd.Parameters(“State”).Value = c.State
cmd.Parameters(“Zip”).Value = c.Zip
cmd.Parameters(“Phone”).Value = c.Phone
cmd.Parameters(“EMailAddress”).Value = c.EMailAddress
cmd.Parameters(“DateAdded”).Value = c.DateAdded
cmd.Parameters(“DateUpdated”).Value = c.DateUpdated
cmd.Parameters(“MailingList”).Value = c.MailingList
cmd.Parameters(“Comments”).Value = c.Comments
cmd.Execute
If Err.Number 0 Then
App.LogEvent _
“Customer(PutCustomer): Can’t update the record “ & _
“for CustomerId “ & _
FormatNumber(c.CustomerId, 0) & “. Error: “ & _
Err.Description & “-” & _
Hex(Err.Number)
PutCustomer = Err.Number
End If
db.Close
o.SetComplete
Set cmd = Nothing
Set db = Nothing
Set o = Nothing
End Function
389
390
Part IV ✦ COM + Transactions, and M essage Queues
Yo u may be wo ndering why I c ho se to use the Update statement, rather than
update the database using a Recordset o bjec t. The answer is really simple: the
Update statement is mo re effic ient in this situatio n. In o rder to use a Recordset,
yo u wo uld have to retrieve the rec o rds a sec o nd time. Then yo u wo uld have to
c hange the values in the c urrent rec o rd and use the Update metho d to send the
c hanges bac k to the database. In this c ase, simply send the update direc tly to the
server.
Installing the transaction into COM +
The COM+ transac tio n server is managed by using the Co mpo nent Servic es utility.
Yo u c an ac c ess this utility by c ho o sing Start ➪ Pro grams ➪ Administrative To o ls ➪
Co mpo nent Servic es (see Figure 18-4).
To add yo ur applic atio n to the COM+ transac tio n server, yo u need to perfo rm these
steps:
1. Cho o se Start ➪ Pro grams ➪ Administrative To o ls ➪ Co mpo nent Servic es fro m
the Windo ws taskbar.
2. Under Co nso le Ro o t, o pen COM+ Applic atio ns by selec ting Co mpo nent
Servic es, then Co mputers and the name o f the c o mputer o n whic h yo u want
to c reate servic e.
3. Right c lic k o n Co mpo nent Servic es and c ho o se New ➪ Applic atio n fro m the
po p-up menu. This starts the COM Applic atio n Install Wizard.
4. Press Next fro m the welc o me sc reen and then c lic k o n the Create an empty
applic atio n butto n.
5. On the Create Empty Applic atio n windo w, enter the name fo r yo ur new applic atio n and c ho o se Server Applic atio n (see Figure 18-6).
6. Clic k Next to display the Set Applic atio n Identity windo w sho wn in Figure 18-7.
Cho o se the user ac c o unt under whic h the applic atio n will run. Yo u c an c ho o se
to use the sec urity o f the user name who is lo gged o nto the server’s c o nso le
(the interac tive user) when the applic atio n is run. Yo u may also enter the name
and passwo rd o f a spec ific user. Clic k Next to go to the last step o f the wizard.
7. Clic k Finish to install the empty applic atio n.
Note
Security can be difficult: For testing purposes, I suggest that you use the user
nam e of the interactive user logged onto the server’s console. Then you should
sign on as Adm inistrator (or another user nam e w ith the sam e privileges as
Adm inistrator). This w ill rem ove m ost of the security restrictions on your transactions. Once the transactions have been debugged, you can go back and create a
specific user nam e w ith only the privileges needed to run the transaction.
Chapter 18 ✦ Using COM + Transactions
Figure 18-6: Entering the nam e of the application
Figure 18-7: Associating the application w ith a
user nam e
Onc e yo u have an empty applic atio n, yo u need to impo rt yo ur Ac tiveX DLL using
these steps in the Co mpo nent Servic es utility (c ho o se Start ➪ Pro grams ➪
Administrative To o ls ➪ Co mpo nent Servic es in Windo ws 2000).
1. Expand the applic atio n yo u just c reated to display the Co mpo nents and Ro les
fo lders beneath it.
2. Right c lic k o n the Co mpo nents fo lder and selec t New ➪ Co mpo nent fro m the
po p-up menu. This will start the COM Co mpo nent Install Wizard.
391
392
Part IV ✦ COM + Transactions, and M essage Queues
3. Clic k Next to mo ve to the Impo rt o r Install a Co mpo nent step and c lic k o n
Install New Co mpo nent(s) butto n.
4. A File Open dialo g bo x will be displayed. Cho o se the name o f the DLL file yo u
just c reated and c lic k o n the Open butto n to display the Install New Co mpo nents
dialo g bo x with the file yo u just selec ted (see Figure 18-8). If yo u need to install
mo re than o ne file, press the Add butto n.
5. After yo u have selec ted the files to be installed, c lic k Next to go to the last
step o f the wizard and press Finish to add the c o mpo nent to the applic atio n.
Figure 18-8: Selecting the nam e of your ActiveX DLL
Building a simple test program
In o rder to test the COM+ transac tio ns, I c reated simple IIS Applic atio n. This pro gram respo nds to the URL http://Athena/VB6DB18/VB6DB18.ASP with a Web
page, as sho wn in Figure 18-9.
Tip
IIS Applications are neat: My favorite feature in Visual Basic 6 is the ability to create a com piled, Web server-based application using IIS Applications. IIS
Applications are generally m ore efficient than ASP applications and they are m ore
secure because the source code is separate from the executable program .
When so meo ne enters the URL to run the IIS Applic atio n, IIS will trigger the
WebClass_Start event sho wn in Listing 18-8. Depending o n the request, o ne o f
three things will happen. If no fo rm info rmatio n is inc luded, a blank Web fo rm will be
displayed, with default values fo r the Customer o bjec t. If a GetCustomer request is
made, then the CustomerId value fro m the fo rm will be passed to the GetCustomer
transac tio n to retrieve the spec ified c usto mer. If a PutCustomer request is made,
then the info rmatio n o n the fo rm will be passed to the PutCustomer metho d to
update the database. A fo rm with the info rmatio n abo ut the c urrent c usto mer is
returned in bo th the PutCustomer and GetCustomer requests.
Chapter 18 ✦ Using COM + Transactions
Figure 18-9: View ing address inform ation returned by the COM+
transaction
Listing 18-8: The WebClass_Start event in Address
Information
Private Sub WebClass_Start()
Dim c As Cust.Customer
Dim ci As Object
If Len(Request.Form(“GetCustomer”)) > 0 Then
Set ci = CreateObject(“CustInfo.CustomerInfo”)
Set c = ci.GetCustomer(CLng(Request.Form(“CustomerId”)))
Set ci = Nothing
ElseIf Len(Request.Form(“PutCustomer”)) > 0 Then
Set ci = CreateObject(“CustInfo.CustomerInfo”)
Set c = New Cust.Customer
c.CustomerId = Request.Form(“CustomerId”)
c.Name = Request.Form(“Name”)
c.Street = Request.Form(“Street”)
c.City = Request.Form(“City”)
c.State = Request.Form(“State”)
c.Zip = Request.Form(“Zip”)
Continued
393
394
Part IV ✦ COM + Transactions, and M essage Queues
Listing 18-8 (continued)
c.Phone = Request.Form(“Phone”)
c.EMailAddress = Request.Form(“DateAdded”)
c.DateUpdated = Request.Form(“DateUpdated”)
If Request.Form(“MailingList”) = “ON” Then
c.MailingList = True
Else
c.MailingList = False
End If
c.Comments = Request.Form(“Comments”)
ci.PutCustomer c
Set ci = Nothing
Else
Set c = New Cust.Customer
c.CustomerId = 9999
End If
With Response
.Write “”
.Write “”
.Write “Address Information”
.Write “”
.Write “”
.Write “Address Information”
.Write “”
.Write “”
.Write “”
.Write “Customer Id:”
.Write “”
.Write “”
.Write “”
.Write “”
.Write “”
.Write “Name:”
.Write “”
.Write “”
.Write “”
.Write “”
.Write “”
.Write “Street:”
.Write “”
.Write “”
.Write “”
Chapter 18 ✦ Using COM + Transactions
.Write “”
.Write “”
.Write “City/State/Zip:”
.Write “”
.Write “”
.Write “”
.Write “”
.Write “”
.Write “”
.Write “”
.Write “Phone:”
.Write “”
.Write “”
.Write “”
.Write “”
.Write “”
.Write “Date Added/Date Updated:”
.Write “”
.Write “”
.Write “