2011-01-19 20 views
3

在C#中,我有一個更新的DB一個OracleConnection,並且其中C#調用到更新DB遺留VB6 DLL的引用(DLL中,它使用ADODB.Connection對象)。在一個事務中更新數據庫的託管代碼和無代碼代碼?

我需要包裝他們倆在一個大的交易,因此,無論是託管和非託管更新回滾或提交在一起。

我試着切換C#類,使它從System.EnterpriseServices.ServicedComponent繼承,並用[Transaction(TransactionOption.Required)]修飾,然後在啓動調用序列的方法上使用[AutoComplete],最終命中OracleConnection和VB6 DLL調用。

像這樣:

using System.EnterpriseServices; 

{ 
    [Transaction(TransactionOption.Required)] 
    public class MyClassTx: ServicedComponent 
    { 
     private MyClass1 _myClass1; 

     public MyClassTx() 
     { 
     } 

     // This method automatically commits the transaction if it succeeds. 
     [AutoComplete] 
     public void DoStuffTransactionally() 
     { 
     // Calls into different objects, doing some work that I'd like to have 
     // a big transaction around. 
     _MyClass1 = new MyClass1() 
     _MyClass1.DoSomeStuff(); 
     } 
    } 
} 

然而,當我的測試工具試圖實例MyClassTx,我得到這個錯誤:

{System.EnterpriseServices.RegistrationException: Invalid ServicedComponent-derived classes were found in the assembly. 
(Classes must be public, concrete, have a public default constructor, and meet all other ComVisibility requirements) 

我已經驗證了我的課是公共的,具體的,具有一個無參數的構造函數。不過,它不會實例化。

我需要強力型我組裝,放入一個COM +組件之前,我甚至能調試嗎?我會假設,使用VS2010,我可以進入ServicedComponent繼承代碼。

它已經8年,因爲我已經使用COM +,這是我第一次嘗試得到它在C#中工作,所以任何幫助,將不勝感激!

而且,如果我在這裏標題下一個愚蠢的路徑,並還有一個更簡單的方式來獲得我的管理和unamanaged代碼到相同的事務,請賜教!

幾個小時與谷歌並沒有太大的幫助。

非常感謝!

回答

3

好的,我認爲我已經取得了重大進展。

,我需要做額外的步驟,以使這一切工作:

  1. 大會必須設置爲標記有ComVisible特性。
  2. 我不得不設置[組件:System.EnterpriseServices.ApplicationName( 「blahblah」)]值... blahblah成爲COM +包的名稱。
  3. 該程序集必須是強命名的,並使用regsvcs.exe在COM +中註冊。它被設置爲使用庫激活,但我不完全確定是否有必要。我嘗試了它作爲服務器激活,但調用它的代碼拋出了某種COM異常。
  4. 你必須調用OracleConnection.EnlistDistributedTransaction,傳遞ContextUtil.Transaction(投它作爲一個交易)是這樣的:

    connection.EnlistDistributedTransaction((ITransaction)ContextUtil.Transaction);

之後,程序集顯示在組件服務窗口中的COM +應用程序列表中。好極了!

更好的是,當我在VS2010中調試時,當我進入DoStuffTransactionally方法時,組件服務瀏覽器中一個新事務處於活動狀態。

所以,讓我來做我的調試。

但是,要實際獲取事務(包括不僅託管代碼,還要在DoStuffTransactionally內調用更深的VB6代碼),我需要將舊的VB6 COM對象添加到託管代碼所在的COM +應用程序中。由於這個VB6代碼調用Oracle,我不得不修改連接字符串VB6代碼用於使DistribTX = 1和PROMOTABLE TRANSACTION = PROMOTABLE集。之後,代碼正在提交併回滾託管的&非託管DB更改作爲單個事務。

耶!

我的調試會話結束時出現錯誤,這對我沒有任何意義。希望它隻影響調試而不是發佈代碼。錯誤是:

DisconnectedContext was detected 
Message: Context 0x4452b0' is disconnected. Releasing the interfaces from the current context (context 0x444fd0). This may cause corruption or data loss. To avoid this problem, please ensure that all contexts/apartments stay alive until the application is completely done with the RuntimeCallableWrappers that represent COM components that live inside them. 

所以,我希望這有助於某人某一天。