views:

57

answers:

3

Hi

Can someone shed light on what is happening behind the scenes with the SQL Lightweight transaction manager when multiple connections are opened to the same DB?

With the below code, we verified that MSDTC is indeed not required when opening 'multiple connections' to the same database.

In the first scenario (where Txn1 and Txn2 use EntLib 4.1 to open a connection to the same DB and call different SPROCS):

        using (TransactionScope ts = new TransactionScope(TransactionScopeOption.Required))
        {
            DAL1.Txn1();
            DAL2.Txn2();
            ts.Complete();
        }

Tracing this from profiler revealed that the same connection SPID was used for Txn1 and Txn2. OK, fine, after Txn1() was called, the SPID may have been released back into the pool and Txn2() just happened to re-use it.

However, when repeating this experiment and this time holding the connections open:

            using (TransactionScope ts = new TransactionScope(TransactionScopeOption.Required))
            {
                Database db1 = DatabaseFactory.CreateDatabase("db1");
                DAL1.Txn1OnCon(db1);
                Database db2 = DatabaseFactory.CreateDatabase("db1");
                DAL2.Txn2OnCon(db2);
                ts.Complete();
            }

Viewing this from Profiler indicated that the 2 transactions were STILL using the same SPID. What have I missed?

Thanks!

+1  A: 

Quoting from MSDN http://msdn.microsoft.com/en-us/library/8xx3tyca(VS.80).aspx

Connection pooling reduces the number of times that new connections need to be opened. The pooler maintains ownership of the physical connection. It manages connections by keeping alive a set of active connections for each given connection configuration. Whenever a user calls Open on a connection, the pooler looks to see if there is an available connection in the pool. If a pooled connection is available, it returns it to the caller instead of opening a new connection. When the application calls Close on the connection, the pooler returns it to the pooled set of active connections instead of actually closing it. Once the connection is returned to the pool, it is ready to be reused on the next Open call.

Just because a connection was used in a transaction doesn't mean it cannot be available for the next call. I found that If the connection string varied by the slightest thing, such as capitalization of a hostname, then you'd get a new physical connection to the db.

Dan
Thanks Dan - this would mean that there isn't a 1:1 correlation between the EntLib DAAB Database and a physical connection.
nonnb
A: 

OK, my misunderstanding was with DAAB. The DAAB Database opens and closes connections as needed (or obtains / releases them from the pool), i.e. connections aren't held for the lifespan of the DAAB Database object.

By holding the actual connections open, they cannot be reused.

However, this then requires MSDTC to be running as soon as 2 physical connections are open.

            using (TransactionScope ts = new TransactionScope(TransactionScopeOption.Required))
            {
                using (DbConnection dbConn1 = DatabaseFactory.CreateDatabase("sport").CreateConnection())
                using (DbConnection dbConn2 = DatabaseFactory.CreateDatabase("sport").CreateConnection())
                {
                    dbConn1.Open();
                    DAL1.Txn1OnCon(dbConn1);
                    dbConn2.Open();
                    DAL2.Txn2OnCon(dbConn2);
                    DAL1.Txn1OnCon(dbConn1);
                    ts.Complete();
                }
            }
nonnb
+1  A: 

Sql 2005 or Sql 2008?
If you use sql 2008, a sequence of open+close connections are not escalated to a distributed transaction. But all the connection must use exactly the same connection string.

(pseudo-code)

string connstring = "...."
using (TransactionScope ts=...)
{
  c1 = new connection(connstring );
  c1.open
  ...use c1
  c1.close

  c2 = new connection(connstring );
  c2.open
  ...use c2
  c2.close

  ts.complete()
}

The same code with sql2005 escalates to distributed transaction --> yuo need MSDTC

Fabrizio
Thanks Fabrizio - my post below - I had assumed that by keeping my DAAB Database in scope that the connection would be held in scope as well, but this was not the case. But you are right - the same conn will be reassigned if it is closed and reopened.
nonnb