托管和非托管代码在一个事务中更新数据库?

在C#中,我有一个更新数据库的OracleConnection,以及对C#调用以更新数据库的旧版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继承代码。 我使用COM +已经有8年了,这是我第一次尝试使用C#,所以任何帮助都会非常感激! 此外,如果我在这里走一条愚蠢的道路并且有更简单的方法将我的托管和非托管代码放入同一个交易中,请赐教! 谷歌的几个小时没有多大帮助。 非常感谢!!     
已邀请:
好的,我认为我在这方面取得了重大进展。 我需要做的其他步骤才能完成所有工作: 大会必须设置为ComVisible。 我不得不设置[assembly:System.EnterpriseServices.ApplicationName(“blahblah”)]值... blahblah成为COM +包的名称。 程序集必须是强名称,并使用regsvcs.exe在COM +中注册。它设置为使用库激活,但我不完全确定是否有必要。我尝试将其作为服务器激活,但调用它的代码抛出了某种类型的COM异常。 您必须调用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设置。在那之后,代码正在提交并回滚托管&非托管数据库更改为单个事务。 好极了! 我在调试会话结束时遇到错误,这对我没有意义。希望它只影响调试而不是发布代码。错误是:
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.
所以,我希望有一天这会帮助某人。     

要回复问题请先登录注册