Интеграция транзакционных компонентов служб Enterprise Services
Windows Communication Foundation (WCF) предоставляет автоматический механизм интеграции с корпоративными службами (см. раздел "Интеграция с приложениями COM+"). Однако для разработки служб, которые внутренне используют транзакционные компоненты, размещенные внутри служб Enterprise Services, может потребоваться гибкость. Поскольку функция транзакций WCF основана на System.Transactions инфраструктуре, процесс интеграции корпоративных служб с WCF идентичен тому, что для указания взаимодействия между System.Transactions службами Enterprise Services и корпоративными службами, как описано в разделе "Взаимодействие с корпоративными службами и транзакциями COM+".
Чтобы обеспечить требуемый уровень взаимодействия между входящей поточной транзакцией и транзакцией контекста COM+, реализация службы должна создать экземпляр TransactionScope и использовать соответствующее значение из перечисления EnterpriseServicesInteropOption.
Интеграция служб Enterprise Services с операцией службы
В представленном ниже коде показана операция с разрешенным потоком транзакций, которая создает область TransactionScope с параметром Full. В этом сценарии используются следующие условия.
Если клиент передает транзакцию, операция, включая вызов компонента Enterprise Services, выполняется в рамках области этой транзакции. Использование параметра Full обеспечивает синхронизацию транзакции с контекстом System.EnterpriseServices. Это означает, что внешняя транзакция для System.Transactions и System.EnterpriseServices одна и та же.
Если клиент не передает транзакцию, при присвоении TransactionScopeRequired значения
true
для операции создается новая область транзакции. Аналогично, использование параметра Full обеспечивает идентичность транзакции операции и транзакции, используемой внутри контекста компонента System.EnterpriseServices.
Любые дополнительные вызовы метода также происходят в пределах области той же транзакции операции.
[ServiceContract()]
public interface ICustomerServiceContract
{
[OperationContract]
[TransactionFlow(TransactionFlowOption.Allowed)]
void UpdateCustomerNameOperation(int customerID, string newCustomerName);
}
[ServiceBehavior(TransactionIsolationLevel = System.Transactions.IsolationLevel.Serializable)]
public class CustomerService : ICustomerServiceContract
{
[OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
public void UpdateCustomerNameOperation(int customerID, string newCustomerName)
{
// Create a transaction scope with full ES interop
using (TransactionScope ts = new TransactionScope(
TransactionScopeOption.Required,
new TransactionOptions(),
EnterpriseServicesInteropOption.Full))
{
// Create an Enterprise Services component
// Call UpdateCustomer method on an Enterprise Services
// component
// Call UpdateOtherCustomerData method on an Enterprise
// Services component
ts.Complete();
}
// Do UpdateAdditionalData on an non-Enterprise Services
// component
}
}
Если между текущей транзакцией операции и вызовами транзакционных компонентов Enterprise Services синхронизация не требуется, при создании экземпляра None используйте параметр TransactionScope.
Интеграция служб Enterprise Services с клиентом
В представленном ниже клиентском коде показано использование экземпляра TransactionScope с параметром Full. В этом сценарии вызовы операций службы, которые поддерживают поток транзакций, происходят в рамках области той же транзакции, что и вызовы компонентов Enterprise Services.
static void Main()
{
// Create a client
CalculatorClient client = new CalculatorClient();
// Create a transaction scope with full ES interop
using (TransactionScope ts = new TransactionScope(
TransactionScopeOption.Required,
new TransactionOptions(),
EnterpriseServicesInteropOption.Full))
{
// Call Add calculator service operation
// Create an Enterprise Services component
// Call UpdateCustomer method on an Enterprise Services
// component
ts.Complete();
}
// Closing the client gracefully closes the connection and
// cleans up resources
client.Close();
}