HighTechTalks DotNet Forums  

Serviced components and database connections...

Dotnet Framework (Component Services) microsoft.public.dotnet.framework.component_services


Discuss Serviced components and database connections... in the Dotnet Framework (Component Services) forum.



Reply
 
Thread Tools Search this Thread Display Modes
  #1  
Old   
Hans Dingemans
 
Posts: n/a

Default Serviced components and database connections... - 01-19-2006 , 02:39 PM






Hi,

A serviced component with transaction attribute Required connects to SQL
Server via an inline coded connection string and does some work in the
database. It also creates and calls another component with transaction
Required (so joins the current txn) that does work in the same or another
SQL instance.

Out of curiosity, how does COM+ know that all this belongs to ONE logical
transaction. What logic makes sure that the Open methods of ADO.NET (or
ADO?) of the components are communicated to COM+ so that it knows what
database connections are enlisted in the txn?

Thanx for any educational resonse ;-)

Hans



Reply With Quote
  #2  
Old   
Tomas Restrepo \(MVP\)
 
Posts: n/a

Default Re: Serviced components and database connections... - 01-19-2006 , 03:59 PM






Hans,

Quote:
A serviced component with transaction attribute Required connects to SQL
Server via an inline coded connection string and does some work in the
database.
You might want to avoid hardcoding your connection strings

Quote:
It also creates and calls another component with transaction Required (so
joins the current txn) that does work in the same or another SQL instance.

Out of curiosity, how does COM+ know that all this belongs to ONE logical
transaction. What logic makes sure that the Open methods of ADO.NET (or
ADO?) of the components are communicated to COM+ so that it knows what
database connections are enlisted in the txn?
COM+ knows it because the way your components are configured. Also, it knows
because when an instance of the components is created, COM+ knows about this
and then creates a special context in memory in which to run the objects
themselves, and it intercepts calls coming into and coming out of this
context.

When COM+ creates the transaction for the first component (which it knows to
do because the registration in the catalog tells it the component requires
it), it associates it with the context the object was created in. When the
object then creates an instance of the second component, COM+ notices that
the second component can run inside the same transaction as the first one,
and then configures the new context (to run the second object in) to point
to the same DTC transaction as the first one.

Finally, the reason why the ADO.NET connections maginally join this
transaction is because the ADO.NET providers that support distributed
transactions explicitily check when you request a connection if they are
being called from inside a COM+ context that is associated with a
transaction, and if so, join the connection to the transaction before
handing it back to your code for using it.

A book that explains this in heavy detail is Tim Ewald's Transactional COM+,
or Juval Löwy's "COM and .NET Component Services".
Here are some good articles on the topic, as well:

http://msdn.microsoft.com/msdnmag/issues/01/10/complus/
http://www.awprofessional.com/articles/article.asp?p=167771&rl=1
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cossdk/html/50ccf75e-2652-4254-a771-af83cc9248b3.asp


--
Tomas Restrepo
tomasr (AT) mvps (DOT) org
http://www.winterdom.com/




Reply With Quote
  #3  
Old   
Hans Dingemans
 
Posts: n/a

Default Re: Serviced components and database connections... - 01-19-2006 , 04:36 PM




Quote:
You might want to avoid hardcoding your connection strings
Of course! What I meant is that "only the component knows what SQL Server is
gonna be used"

Quote:
Finally, the reason why the ADO.NET connections magically join this
transaction is because the ADO.NET providers that support distributed
transactions explicitily check when you request a connection if they are
being called from inside a COM+ context that is associated with a
transaction, and if so, join the connection to the transaction before
handing it back to your code for using it.

That helps! But still sounds a bit like magic. Exactly when does COM+ peek
what SQL Server is gonna be used (and how), or perhaps the other way round,
when does the ADO.NET connection tell COM+?

Also thanx for the pointers, but haven't looked there for answers yet...

Hans




Reply With Quote
  #4  
Old   
Tomas Restrepo \(MVP\)
 
Posts: n/a

Default Re: Serviced components and database connections... - 01-19-2006 , 08:51 PM




Hi Hans,

Quote:
That helps! But still sounds a bit like magic. Exactly when does COM+ peek
what SQL Server is gonna be used (and how), or perhaps the other way
round, when does the ADO.NET connection tell COM+?
That last part is exactly what happens. The Data Access Providers are the
ones that know what server they need to open the connection to and interact
(alongside the database server) with the DTC to enroll the connection into
the distributed transaction.

In the case of, for example, SqlClient, exactly where this happens is fairly
underneath the covers, since the connection pooling support has to be aware
of this happening (a connection that was joined to a transaction cannot be
joined to another transaction until that one is done, so this changes the
basic criteria for handling out connections from the pool).

If you want to know exactly where this happens, check out the code for the
TryGetResourceFromContext() method of the
System.Data.SqlClient.ConnectionPool class, which basically uses the
System.EnterpriseServices.ContextUtil class to check for the COM+ context
and verify if it has a transaction associated with it.

Also, you might be interested in knowing that there are two other options
that control how this process happens:
- If you don't want your connections to join a DTC transaction available in
the COM+ context, you can simply especify "Enlist=false" as part of the
connection string
- You can also manually join a sql connection to a DTC transaction via the
EnlistDistributedTransaction() method of the SqlConnection class.


--
Tomas Restrepo
tomasr (AT) mvps (DOT) org
http://www.winterdom.com/




Reply With Quote
  #5  
Old   
Hans Dingemans
 
Posts: n/a

Default Re: Serviced components and database connections... - 01-20-2006 , 09:38 AM



Lorenzo,

I cannot find any info about System.Data.SqlClient.ConnectionPool or
TryGetResourceFromContext in neither the 2003 nor 2005 documentation of
Visual Studio. The class seems not to exist, not even visible with
QuickStart's .NET Framework Class Browser which uses Reflection to peek into
the actual assemblies!?
Google has found one (as in 1) hit on TryGetResourceFromContext and "only"
10200 hits on System.Data.SqlClient.ConnectionPool. Seems to be not the
coolest identifiers for the majority of developers...

Cheers,
Hans


"Tomas Restrepo (MVP)" <tomasr (AT) mvps (DOT) org> wrote

Quote:
Hi Hans,

That helps! But still sounds a bit like magic. Exactly when does COM+
peek what SQL Server is gonna be used (and how), or perhaps the other way
round, when does the ADO.NET connection tell COM+?

That last part is exactly what happens. The Data Access Providers are the
ones that know what server they need to open the connection to and
interact (alongside the database server) with the DTC to enroll the
connection into the distributed transaction.

In the case of, for example, SqlClient, exactly where this happens is
fairly underneath the covers, since the connection pooling support has to
be aware of this happening (a connection that was joined to a transaction
cannot be joined to another transaction until that one is done, so this
changes the basic criteria for handling out connections from the pool).

If you want to know exactly where this happens, check out the code for the
TryGetResourceFromContext() method of the
System.Data.SqlClient.ConnectionPool class, which basically uses the
System.EnterpriseServices.ContextUtil class to check for the COM+ context
and verify if it has a transaction associated with it.

Also, you might be interested in knowing that there are two other options
that control how this process happens:
- If you don't want your connections to join a DTC transaction available
in the COM+ context, you can simply especify "Enlist=false" as part of the
connection string
- You can also manually join a sql connection to a DTC transaction via the
EnlistDistributedTransaction() method of the SqlConnection class.


--
Tomas Restrepo
tomasr (AT) mvps (DOT) org
http://www.winterdom.com/




Reply With Quote
Reply




Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Powered by vBulletin Version 3.5.4
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.