Могу ли я предотвратить откат транзакции WCF при возникновении ошибки?

Рассмотрим следующую службу WCF, которая участвует в распределенной транзакции. Обычное поведение WCF - откат транзакции в случае возникновения какой-либо ошибки. Есть ли способ изменить это поведение?

Контракт на обслуживание:

[ServiceContract]
public interface ITestService {
    [OperationContract]
    [FaultContract(typeof(TestServiceFault))]
    void ThrowError();
    [OperationContract]
    void DoSomething();
    [OperationContract]
    void DoSomethingElse();
}

[DataContract]
public class TestServiceFault{}

Реализация услуги:

class TestService : ITestService {
    [OperationBehavior(TransactionScopeRequired = true)]
    [TransactionFlow(TransactionFlowOption.Mandatory)]
    public void ThrowError() {
        throw new FaultException<TestServiceFault>(new TestServiceFault());
    }
    [OperationBehavior(TransactionScopeRequired = true)]
    [TransactionFlow(TransactionFlowOption.Mandatory)]
    public void DoSomething() {
        //
        // ...
        //
    }
    [OperationBehavior(TransactionScopeRequired = true)]
    [TransactionFlow(TransactionFlowOption.Mandatory)]
    public void DoSomethingElse() {
        //
        // ...
        //
    }
}

Фрагмент реализации клиента:

using(new TransactionScope()) {
    testServiceClient.DoSomething();

    try {
        testServiceClient.ThrowError();
    } catch(FaultException<TestServiceFault>) {}

    testServiceClient.DoSomethingElse();
}

Когда исключение FaultException выбрасывается из ThrowError (), WCF откатывает распределенную транзакцию, которая включает работу, выполняемую DoSomething (). Затем клиентский вызов DoSomethingElse () завершается ошибкой с сообщением Не удалось демаршалировать текущую транзакцию. Произошло следующее исключение: транзакция уже была явно или неявно зафиксирована или прервана.

В моем конкретном сценарии такое поведение нежелательно. Я бы хотел перехватить исключение на стороне клиента и продолжить заниматься своими делами. Если возникают какие-либо исключения, которые я не улавливаю, клиент откатит транзакцию.

Примечание. Этот вопрос дублирует Как обработать FaultException в WCF без прерывания всей транзакции?, но принятого ответа нет Меня это не устраивает - важно, чтобы все операции выполнялись в рамках одной транзакции.


person jon without an h    schedule 17.02.2011    source источник
comment
Если у вас есть только одна область транзакции, то сбой приведет к откату всей транзакции - в конце концов, в этом весь смысл. Если вы хотите иметь изолированную суб-транзакцию, которая может завершиться ошибкой, не влияя на транзакцию в целом, вам необходимо использовать подход, показанный в другом вопросе. Я не вижу другого подхода - выберите одно из этих двух решений - другого волшебного пути нет ...   -  person marc_s    schedule 17.02.2011
comment
Да, я понимаю суть такого поведения, но я хотел бы сказать, что ошибки, определенные в контракте (или, возможно, в некотором подмножестве), не являются ошибками. Но похоже, что это невозможно.   -  person jon without an h    schedule 19.02.2011


Ответы (1)


ну, вы можете попробовать установить TransactionAutoComplete = false на стороне службы, а затем использовать SetTransactionComplete (), чтобы исключение не откатило вашу работу.

person Menahem    schedule 20.02.2011
comment
Это работает, спасибо! Я хотел бы найти точку расширения, где я смогу это сделать, чтобы применить ее как поведение к своим операциям. - person jon without an h; 24.02.2011
comment
рад слышать, чтобы применить это как поведение, возможно, вы можете использовать некоторую аспектно-ориентированную фреймворк, чтобы применить завершенный tran к указанным вами типам исключений. (возможно, на этапе после действия) - person Menahem; 24.02.2011