Mike,
> I have a presentation layer (it can be an web page or a windows form), a
> Business Layer where business rules are enforced and a Data Layer which
[quoted text clipped - 21 lines]
> Has anyone successfully been able to do this? Any help will be greatly
> appreciated.
I'm not sure using your components in such a stateful fashion might be the
best option, and, in reality, it won't work as you're doing it now.
The problem is that transaction lifetime in COM+ is tied to component
(object) lifetime (actually, to the context the root object of the
transaction lives in, but it's a non-essential distinction for our
discussion here). So, in other words, COM+ won't try to commit/rollback your
distributed transaction until *after* your component is deactivated (think
destroyed/released... unless you're using object pooling).
Given this, what's going on is this:
- You create your object, transaction is created (it might be created later,
but this works)
- You call a method on your object that does data access under the
transaction
- method sets member variable
- you deactivate the object without knowing (possibly you use [AutoComplete]
or use ContextUtil.SetComplete()/SetAbort())
- Object is released, COM+ commits/aborts transaction
- You try to access member property
- COM+ creates a new object under the hood and makes it look as if it was
the original one.... minus any state (this is possible because all
transactional objects support Just In Time Activation (JITA))
See the problem?
You can avoid this one of two ways:
1- Delay object deactivation: Don't use [AutoComplete] or
SetComplete()/SetAbort(). Instead just vote on the transaction in your
method by using ContextUtil.MyTransactionVote or
ContextUtil.EnableCommit()/DisableCommit(). That way you can call the method
and use the same object reference to access any state. However, now the
calling code is responsible for forcing object deactivation by either
explicitly disposing of the object or by calling a method on it that
triggers the deactivation. This is key, as otherwise the transaction will
linger open until the GC reclaims your object, killing
performance/scalability
2- Use something like the Shared Property Manager. This is ugly, not very
scalable, and possibly overkill.
My take is that you're really looking at something like 1, in which case I
strongly recommend taking a good look at the COM+ documentation on how JITA
works and how it affects transaction lifetime. Here's a good place to start:
*
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cossdk/html/dbc
7b257-8506-42c8-8a78-3474c6d4f4b6.asp
*
http://msdn.microsoft.com/library/en-us/cossdk/html/50086e6e-024b-4a09-b8be-8f55
b6bfadb2.asp?frame=true
A good book might also help; I recommend "Transactional COM+" by Tim Ewald.
He covers this issue in extreme detail, and its a great book all around on
building scalable systems.

Signature
Tomas Restrepo
tomasr@mvps.org
http://www.winterdom.com/
Mike Malter - 22 Aug 2005 20:18 GMT
Tomas,
Ah, I see. Your insight into a solution is insightful, but does not really solve my
problem. I am probably going to have to use ADO transactions which does not kill
member variable values after a transaction is complete.
My design goal is to have a business layer with objects that are transaction aware
and any object can participate in a transaction. Then this business layer is the
outer perimeter protecting my data.
Using ADO, I have to explicitly include everything I want in a transaction, using
COM+ all I have to do is to participate in a transaction.
My wish is that member variables would be left alone since the transaction has
nothing to do with the contents. ASP & VB allowed me to do COM+ and keep the
contents of member variables through the transaction.
It is like they give something with one hand and take something away with the other.
Thanks again for taking the time to present me with a well though out solution rather
than regurgitate something that someone else wrote.
> Mike,
>
[quoted text clipped - 71 lines]
> covers this issue in extreme detail, and its a great book all around on building
> scalable systems.
Tomas Restrepo (MVP) - 23 Aug 2005 00:46 GMT
Mike,
> Ah, I see. Your insight into a solution is insightful, but does not
> really solve my problem. I am probably going to have to use ADO
[quoted text clipped - 12 lines]
> has nothing to do with the contents. ASP & VB allowed me to do COM+ and
> keep the contents of member variables through the transaction.
Actually, object state has *everything* to do with transactions. Do you want
the end result of your transaction and your object state to disagree on what
the actual state of the system is? I would certainly hope not. Remember: In
COM+, transaction lifetime is *always* tide to the lifetime of the
transaction root object/context. this is a key property of the entire COM+
transactional design. Not only that, but what you're asking can become a
scalability problem in some cases.
Notice I didn't really give you a solution, I just explained why it would
*not* work as you expected. You can certainly combine transactions and
object state in COM+, you just can't expect to have the object alive after
you force transaction commit/rollback.
Now, how exactly were you using transactions with VB while keeping object
state? I'm curious...
BTW, have you ever read Tim Ewald's Transactional COM+ book? He does cover
all of this is fine detail...

Signature
Tomas Restrepo
tomasr@mvps.org
http://www.winterdom.com/
Mike Malter - 24 Aug 2005 20:09 GMT
Tomas,
Thanks again for your insight and thoughtful reply.
State is what state is designed to be. In this case, the design of state is not
helpful to me, it could just as easily been designed to keep contents of member
variables intact.
With regard to COM+ and asp. What I used to do in my VB code was to create member
variables in the class as well as mark it for transaction. I was then able to assign
values to these member variables prior to the transaction and when the transaction
was complete, the values were still there. I don't know why ASB VB worked the way it
did. I remember registering my VB objects with com and I even had my connection
string in there.
So, what I am doing now is to have very flat objects transaction aware objects with
no member variables. On one hand, this could be better because when instantiating an
object I am not also using memory for all class members.
I have written a data layer that emulates the distributed transactional model in that
constructors are passed values that indicate a transaction is already in place, I am
running into some problems and refining it. I'm still looking for the holy grail of
transactional objects that keep state through the transaction.
> Mike,
>
[quoted text clipped - 30 lines]
> BTW, have you ever read Tim Ewald's Transactional COM+ book? He does cover all of
> this is fine detail...