Итак, у нас должен быть главный класс, который создает транзакцию. И он должен создавать новую транзакцию. Это описывается в свойствах.
Внутри классу нужно получить указатель на транзакцию.
Dim context As ObjectContext Set context = GetObjectContext
Этот класс будет родоначальником транзакции. Он будет создавать классы. Создаваемые классы должны иметь свойства наследования транзакции.
Эти классы должны создаваться в контексте транзакции.
Dim sql As ClassSQL Dim oracle As ClassORACLE Set sql = context.CreateInstance("ProjectTransaction.ClassSQL") Set oracle = context.CreateInstance("ProjectTransaction.ClassORACLE")
Дальше вызываются методы. Но внимание. В этом главном классе должна быть обработка ошибок и метод, который начинает выполнение транзакций, должен возвращать результат. Давайте посмотрим весь код метода главного класса:
Public Function Method() As Boolean On Error GoTo ErrorHandles Dim context As ObjectContext Dim sql As ClassSQL Dim oracle As ClassORACLE Set context = GetObjectContext Set sql = context.CreateInstance("ProjectTransaction.ClassSQL") Set oracle = context.CreateInstance("ProjectTransaction.ClassORACLE") sql.Method oracle.Method Set sql = Nothing Set oracle = Nothing Method = True Exit Function ErrorHandles: Set sql = Nothing Set oracle = Nothing GetObjectContext.SetAbort Method = False End Function
Основа здесь обработка ошибок. Если метод класса sql вызовет SetAbort, то ни классам внутри этой транзакции, ни к метода созданных объектов обратиться будет нельзя. Тут же будет ошибка. Итак, идея основана на том, что если кто-то вернет SetAbort, то к классам и функциям обращаться внутри этой транзакции не получится, если стоит обработка ошибки, то она будет генерироваться. Смотрите. Метод класса SQL сразу порождает:
Public Sub Method() GetObjectContext.SetAbort End Sub
И при попытке вызвать метод ORACLE тут же срабатывает обработка ошибки и метод класса возвращает FALSE. То же самое будет и при попытке создать класс, если кто-то вызвал SetAbort. Контекст транзакции блокируется. Вот и вся идея. Можно в транзакцию поместить огромное количество классов, которые последовательно обращаются друг к другу используя разные БД и методы доступа к ним. Только кто-то вернет SetAbort, как тут же нельзя будет вызвать следующий метод, это приведет к генерации ошибки и это скажет нам, что транзакция не прошла. Не нужно всякие там флаги выставлять и так далее.