Управляемый и неизменный код обновления БД в рамках одной транзакции? - PullRequest
3 голосов
/ 19 января 2011

В C # у меня есть OracleConnection, которая обновляет БД, и ссылка на устаревшую библиотеку VB6, в которую C # обращается для обновления БД (в этой библиотеке используется объект 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 #, поэтому любая помощь будет принята с благодарностью!

Кроме того, если я иду по глупому пути здесь, и есть более простой способ вставить мой управляемый и неуправляемый код в одну и ту же транзакцию, пожалуйста, просветите меня!

Несколько часов сGoogle мало чем помог.

Большое спасибо !!

1 Ответ

3 голосов
/ 20 января 2011

Хорошо, я думаю, что добился значительного прогресса в этом.

Дополнительные шаги, которые мне нужно было сделать, чтобы все это заработало:

  1. Сборка должна быть установлена ​​как ComVisible.
  2. Мне нужно было установить значение [assembly: System.EnterpriseServices.ApplicationName ("blahblah")] ... blahblah становится именем пакета COM +.
  3. Сборка должна была иметь строгое имя и была зарегистрирована в COM + с помощью regsvcs.exe. Он настроен на использование активации библиотеки, но я не совсем уверен, если это необходимо. Я пробовал это как активацию сервера, но вызывающий его код вызывал какое-то исключение COM.
  4. Вы должны вызвать OracleConnection.EnlistDistributedTransaction, передавая ContextUtil.Transaction (приведенный как транзакция), например:

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

После этого сборка отображалась в списке приложений COM + в окне «Службы компонентов». Ура!

Еще лучше, когда я отлаживал в VS2010, когда я попал в метод DoStuffTransactionally, в проводнике служб компонентов была активна новая транзакция.

Итак, позвольте мне сделать мою отладку.

Однако, чтобы фактически получить Транзакцию, включающую не только управляемый код, но и устаревший код VB6, вызываемый глубже внутри DoStuffTransactionally, мне нужно было добавить устаревшие COM-объекты VB6 в приложение 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.

Итак, я надеюсь, что это когда-нибудь кому-нибудь поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...