2010-09-02 14 views
0

有人可以通過使用Microsoft Data Access Application Block (DAAB)在多個連接對同一個數據庫打開時使用SQL輕量級事務管理器闡明幕後發生的情況嗎?NET TransactionScopes和SQL 2005輕量級事務管理器 - 多個連接相同的SPID?

通過下面的代碼,我們驗證了在打開'多個連接'到同一個數據庫時MSDTC確實不是必需的。

這是我測試的第一種方案:(其中TXN1和Txn2使用EntLib 4.1開到同一數據庫的連接,並調用不同的存儲過程)

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

從探查跟蹤這表明,相同的連接SPID用於Txn1和Txn2。在調用Txn1()後,Sql SPID將被釋放回池中,並且Txn2()可以重新使用它。

然而,重複該實驗,此時保持的連接打開時:

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

從探查觀看此表明2個交易是仍然使用相同的SPID。我期待TransactionScope已升級到DTC,因爲應該要求分佈式事務來控制2個併發連接。我錯過了什麼?

回答

1

MSDNhttp://msdn.microsoft.com/en-us/library/8xx3tyca(VS.80).aspx

連接池引用減少新連接需要 被打開的次數 。池中的物理連接的所有權保持爲 。 它通過保持 爲每個給定連接配置的 激活一組活動連接來管理連接。 只要用戶在 連接上調用打開,便池會查看 池中是否有可用的連接 。如果池連接是 可用,它會將其返回給調用者 而不是打開新的連接。 當應用程序調用關閉 連接時,池將它返回 到活動的 連接的集合集合,而不是實際上關閉它的 。一旦連接被 返回到池中,就準備好 在下一次打開呼叫時被重用。

僅僅因爲在事務中使用連接並不意味着它不能用於下一次調用。我發現,如果連接字符串由於某種細微的事情而變化,例如主機名的大小寫,那麼你會得到一個到數據庫的新物理連接。

+0

感謝丹 - 這將意味着沒有一個1:1的相關性EntLib DAAB數據庫和物理連接之間。 – StuartLC 2010-09-08 06:40:09

0

好的,我的誤解是DAAB。 DAAB Database根據需要打開和關閉連接(或從池中獲取/釋放它們),即連接不保留以用於DAAB Database對象的生命週期。

可以按照以下方式手動控制DAAB中的數據庫連接 - 通過保持實際連接處於打開狀態,它們不能重複使用。這就需要MSDTC在2個物理連接打開後立即開始運行,正如我在原始問題中預期的那樣。

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

Sql 2005或Sql 2008?
如果您使用的是sql 2008,則一系列open + close連接不會升級爲分佈式事務。但是所有連接都必須使用完全相同的連接字符串。

(僞代碼)

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() 
} 

與SQL2005相同的代碼升級爲分佈式事務 - >宥需要MSDTC

+0

感謝Fabrizio - 我的文章如下 - 我曾假設通過將DAAB數據庫保持在範圍內,連接將保持在範圍內,但事實並非如此。但是你是對的 - 如果封閉並重新開放,同一個conn將被重新分配。 – StuartLC 2010-09-08 11:23:14