Шаг 3. Повторное использование компонентов
Цели
На этом шаге вы узнаете следующее:
- Повторно используемые компоненты.
- Планирование повторного использования.
Описание
Две предыдущие части этого вводного курса по службам COM+, шаг 1: Создание транзакционного компонента и шаг 2: Расширение транзакции через несколько компонентов показывают, как написать один компонент, который вызывает второй компонент, чтобы помочь в выполнении определенных задач, таких как обновление информации об авторе в базе данных Pubs на Microsoft SQL Server; все действия защищены одной транзакцией. Примеры компонентов посвящены работе по обновлению данных автора и проверке адреса автора, а также обработке транзакций COM+, активации JITи защите параллелизма.
На этом шаге показано, как повторно использовать компоненты, созданные на шагах 1 и 2, и посмотреть, что это означает для проектирования этих компонентов. Как показано на следующем рисунке, это означает создание нового компонента AddNewAuthor
, которое добавляет новых авторов в базу данных путем вызова UpdateAuthorAddress
.
Помимо повторного использования существующих функций компонентов, AddNewAuthor
вызывает другой новый компонент, называемый ValidateAuthorName
. Как показано на предыдущем рисунке, ValidateAuthorName
не является транзакционной. Значение атрибута транзакции для этого компонента остается в параметре по умолчанию (не поддерживается), чтобы исключить ее работу из транзакции. Как показано в примере кода 3, ValidateAuthorName
выполняет запросы только для чтения в базе данных, а сбой этой дополнительной задачи не должен иметь возможности прервать транзакцию. Однако для атрибута транзакции компонента AddNewAuthor
задано значение Обязательный.
Компоненты AddNewAuthor
, UpdateAuthorAddress
и ValidateAuthorAddress
все голосуют в транзакции. В этой транзакции AddNewAuthor
является корневым объектом. COM+ всегда делает первый объект, созданный в рамках транзакции, корневым объектом.
В этом примере повторное использование компонента UpdateAuthorAddress
легко— COM+ автоматически предоставляет ожидаемые службы. Однако результаты будут отличаться, если для значения атрибута транзакции компонента UpdateAuthorAddress
изначально задано значение Требуется новая вместо Обязательные. На первый взгляд обе настройки кажутся похожими; обе гарантируют транзакцию.
требует новую, однако всегда запускает новую транзакцию, в то время как требуется и запускает новую транзакцию только в том случае, если вызывающий объект не является транзакционным. Вы можете увидеть, насколько важно было настроить UpdateAuthorAddress
тщательно и продуманно. В противном случае COM+ может интерпретировать запрос службы по-разному, создавая две несвязанные транзакции, как показано на следующем рисунке, а не один.
Заметка
При повторном использовании компонентов убедитесь, что службы настроены для поддержки желаемого результата.
Пример кода
Компонент AddNewAuthor выполняет пакетные дополнения новых авторов, позволяя объекту оставаться активным до тех пор, пока клиент не выпустит ссылку на объект.
Option Explicit
'
' Purpose: This class is used for adding a new author.
'
' Notes: IMPT: This component implicitly assumes that it will
' always run in a transaction. Undefined results may
' otherwise occur.
'
' AddNewAuthor
'
Public Sub AddNewAuthor( _
ByVal strAuthorFirstName As String, _
ByVal strAuthorLastName As String, _
ByVal strPhone As String, _
ByVal strAddress As String, _
ByVal strCity As String, _
ByVal strState As String, _
ByVal strZip As String, _
ByVal boolContracted As Boolean)
' Handle any errors.
On Error GoTo UnexpectedError
' Verify component is in a transaction.
' The VerifyInTxn subroutine is described in Step 1.
VerifyInTxn
' Get our object context.
Dim objcontext As COMSVCSLib.ObjectContext
Set objcontext = GetObjectContext
' Get the IContextState object.
Dim contextstate As COMSVCSLib.IContextState
Set contextstate = objcontext
' Validate that the author is OK.
' The ValidateAuthorName function is described after this function.
Dim oValidateAuthName As Object
Dim bValidAuthor As Boolean
Set oValidateAuthName = CreateObject("ComplusPrimer.ValidateAuthorName")
bValidAuthor = oValidateAuthName.ValidateAuthorName( _
strAuthorFirstName, strAuthorLastName)
If Not bValidAuthor Then
Err.Raise 999999, "The AddNewAuthor component", _
"You tried to add an author on the banned list!"
End If
' Open the connection to the database.
Dim conn As ADODB.Connection
Set conn = CreateObject("ADODB.Connection")
' Specify the OLE DB provider.
conn.Provider = "SQLOLEDB"
' Connect using Windows Authentication.
Dim strProv As String
strProv = "Server=MyDBServer;Database=pubs;Trusted_Connection=yes"
' Open the database.
conn.Open strProv
' Tell the database to actually add the author; use empty strings
' for this part and rely on the UpdateAuthorAddress
' component to validate the address/phone/etc data.
' Default Contract flag is off.
Dim strUpdateString As String
strUpdateString = "insert into authors values(_
'789-65-1234'," & _
strAuthorLastName & ", " & _
strAuthorFirstName & ", " & _
"'(555) 555-5555', ', ', ', '98765', "
If boolContracted Then
strUpdateString = strUpdateString + "1)"
Else
strUpdateString = strUpdateString + "0)"
End If
conn.Execute strUpdateString
' Close the connection; this potentially allows
' another component in the same transaction to
' reuse the connection from the connection pool.
conn.Close
Set conn = Nothing
' Create the UpdateAuthorAddress component.
Dim oUpdateAuthAddr As Object
Set oUpdateAuthAddr = CreateObject("ComplusPrimer.UpdateAuthorAddress")
' The component throws an error if anything goes wrong.
oUpdateAuthAddr.UpdateAuthorAddress "", strPhone, _
strAddress, strCity, strState, strZip
Set oUpdateAuthAddr = Nothing
' Everything works--commit the transaction.
contextstate.SetMyTransactionVote TxCommit
' Design issue: Allow batch additions of new
' authors in one transaction, or should each new author be added
' in a single new transaction?
contextstate.SetDeactivateOnReturn False
Exit Sub
UnexpectedError:
' There's an error.
contextstate.SetMyTransactionVote TxAbort
contextstate.SetDeactivateOnReturn True
End Sub
Компонент ValidateAuthorName
проверяет имена авторов, прежде чем AddNewAuthor
добавляет имя в базу данных. Этот компонент возвращает ошибку вызывающей стороне, если произойдет что-то неожиданное.
Option Explicit
'
' Purpose: This class is used for validating authors before
' adding them to the database.
'
' Notes: This component doesn't need to be in a transaction because
' it is performing read-only queries on the database,
' especially since these queries are not overlapping with
' any updates of end-user data. If an unexpected error
' happens, let the error go back to the caller who
' needs to handle it.
'
Public Function ValidateAuthorName( _
ByVal strAuthorFirstName As String, _
ByVal strAuthorLastName As String _
) As Boolean
ValidateAuthorName = False
' Open the connection to the database.
Dim conn As ADODB.Connection
Set conn = CreateObject("ADODB.Connection")
' Specify the OLE DB provider.
conn.Provider = "SQLOLEDB"
' Connect using Windows Authentication.
Dim strProv As String
strProv = "Server=MyDBServer;Database=pubs;Trusted_Connection=yes"
' Open the database.
conn.Open strProv
' Suppose another hypothetical table has been added to the Pubs
' database, one that contains a list of banned authors.
Dim rs As ADODB.Recordset
Set rs = conn.Execute("select * from banned_authors")
' Loop through the banned-author list looking for the specified
' author.
While Not rs.EOF
If rs.Fields("FirstName") = strAuthorFirstName And _
rs.Fields("LastName") = strAuthorLastName Then
' This is a banned author.
conn.Close
Set conn = Nothing
Set rs = Nothing
Exit Function
End If
rs.MoveNext
Wend
' None of the added authors found in the banned list.
ValidateAuthorName = True
conn.Close
Set conn = Nothing
Set rs = Nothing
End Function
Сводка
- Существуют случаи, когда компонент не должен участвовать в процессе транзакции.
- COM+ не применяет JIT-активацию или защиту параллелизма для компонентов, не относящихся к транзакциям. Эти службы можно настроить отдельно.
- Конфигурация вызывающего компонента влияет на то, как COM+ интерпретирует запросы службы вызываемого компонента.
Связанные разделы
-
шаг 1. Создание компонента транзакций