2012-09-13 2 views
8

핵심 서비스를 사용하여 발행물 대상에 & 대상을 추가하는 것을 돕기 위해 클래스를 작성했습니다. 대상은 핵심 서비스를 통해 문자열 (XML 내용 포함)로 노출되므로 일반적으로 내 자신의 래퍼를 작성했습니다.CoreService를 사용하여 사용자 정의 클래스에 WCF 트랜잭션 지원을 구현하려면 어떻게해야합니까?

게시 대상을 2 개 업데이트해야한다고 생각했습니다. 두 대상이 동시에 업데이트되도록 트랜잭션 범위를 사용하도록 멋지게 작성하십시오.

그러나 구현하는 데 어려움을 겪고 있습니다.

코드 작업 (사용하여 표준 CoreService WCF 클라이언트) : 성공적으로 Tridion에 게시 목표를 내가 한 변경 사항을 롤백 (나는 scope.Dispose() 전에 깰 경우 확인합니다이 코드를 실행

TransactionOptions txOptions = new TransactionOptions 
        { IsolationLevel = IsolationLevel.ReadCommitted }; 
using(TransactionScope scope = new TransactionScope(
          TransactionScopeOption.Required, txOptions)) 
{ 
    PublicationTargetData publicationTarget1 = (PublicationTargetData)client.Read("tcm:0-1-65537", readOptions); 
    PublicationTargetData publicationTarget2 = (PublicationTargetData)client.Read("tcm:0-2-65537", readOptions); 

    publicationTarget1.TargetLanguage = "JSP"; 
    publicationTarget2.TargetLanguage = "JSP"; 
    client.Save(publicationTarget1, readOptions); 
    client.Save(publicationTarget2, readOptions); 

    // Stop saving 
    scope.Dispose(); 
} 

는 성공적으로 목표를 변경 그런 다음 변경 사항을 "실행 취소"합니다).

"확장 된 게시 대상"클래스를 트랜잭션에서도 사용하려고하면이를 처리 할 수 ​​없습니다.

TransactionOptions options = new TransactionOptions { IsolationLevel = IsolationLevel.ReadCommitted }; 
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, options)) 
{ 
    ExtendedPublicationTarget target1 = new ExtendedPublicationTarget("tcm:0-1-65537"); 
    ExtendedPublicationTarget target2 = new ExtendedPublicationTarget("tcm:0-2-65537"); 
    target1.Destinations.Add(target1.Destinations[0]); 
    target2.Destinations.Add(target2.Destinations[0]); 
    target1.Save(); 
    target2.Save(); 
    scope.Dispose(); 
} 

기본적으로 이것은 질문입니다. 내 .Save() 메소드에 트랜잭션 성을 추가하려면 어떻게해야합니까? 나는이 일을 시도

:

[OperationContract] 
[TransactionFlow(TransactionFlowOption.Allowed)] 
public void Save() 
{ 
    _client.Save(targetData, readOptions); 
} 

그러나이 차이를 만들지 않았다. 제가 현재 거래에 있고 어떻게 든 그 거래를 "사용"하고 있는지 판단 할 수있는 방법이 있습니까? 나는 거래를 요구하고 싶지 않고 단지 하나의 옵션을 운영하기를 원한다.

매우 긴 게시물에 대해 유감스럽게 생각하고 ... 최대한 많은 정보를 제공하고 싶었습니다.

+0

'using' 절에'scope' 변수가 있으므로 명시 적으로'Dispose'를 호출해서는 안됩니다. 대신 'using'블록이 끝나면 자동으로 처리됩니다. –

+0

당신은 "나는 그것을 처량 할 수 없다"고 말한다. 그게 무슨 뜻 이죠? 컴파일러 오류가 발생합니까? 예외? 아니면 코드가 타겟을 업데이트하지 않습니까? (추신 : WCF 트랜잭션이 내가 익숙한대로 명명 된 경우 TransactionScope는 기존 트랜잭션에서 "피기 백"하거나 새 트랜잭션을 시작합니다. 그러나 WCF 트랜잭션에 대한 경험이 없으므로 다른 사람이 그 가정을 확인/정정하는 것을보십시오). –

+0

안녕하세요 프랭크, 나는 그것을 실패하게 만들려고합니다. 그러므로 나의 scope.Dispose() 호출. 첫 번째 예에서는 올바르게 실패하고 두 번째 경우에는 실패합니다. 그냥 내 수업에 추가해야 할 일이 무엇인지 알아 내려고 노력했습니다 ... –

답변

3

이를위한 가장 좋은 자원이다 : 당신은 적어도 하나의 단계를 누락 WCF Transaction Propagation

. 또한 바인딩에 거래를 활성화해야합니다 :

<bindings> 
    <netTcpBinding> 
     <binding name = “TransactionalTCP” transactionFlow = “true” /> 
    </netTcpBinding> 
</bindings> 

내가 트랜잭션에서 현재 오전 어떻게 든 트랜잭션을 "사용"여부를 결정하는 방법이 있나요?

예. 거래 중인지 확인하려면 Transaction.Current를 확인할 수 있습니다. 거래중인 경우 명시 적으로 제외하지 않는 한 거래가 사용됩니다. 그것은 주변 거래에 대한 아름다운/끔찍한 일입니다. WCF Transaction Propagation에서

그림 5 : Transaction.Current.TransactionInformation.DistributedIdentifier이 비어있는 경우

class MyService : IMyContract 
{ 
    [OperationBehavior(TransactionScopeRequired = true)] 
    public void MyMethod(...) 
    { 
     Transaction transaction = Transaction.Current; 
     Debug.Assert(transaction.TransactionInformation. 
        DistributedIdentifier != Guid.Empty); 
    } 
} 

, 다음 트랜잭션은 로컬 및 "흐름"하지 않았다. TransactionFlowOptions.Allowed 구성에서 트랜잭션이 실패하면 자동으로 실패합니다. 그래서 이것은 실제로 확인하는 유일한 방법입니다 ... 그리고 흐르는 것이 당신이 기대하는 것보다 쉽게 ​​일어납니다.

프로덕션 서비스에 tranactions를 사용했을 때 호출자가 트랜잭션이 실제로 흐른 지 확실하지 않았기 때문에 나는 실제로 TransactionFlowOptions.Allowed을 피했습니다. 배포시 바인딩 구성 오류가 발생하면 모든 것이 잘 실행되지만 롤백은 실패합니다 ... 감지하기가 매우 힘듭니다. 그래서 나는 필요로 바꿨다. 그런 다음 발신자이 제공 한 트랜잭션이 실제로 성공적으로 전달되었는지 확인할 수 있습니다. (트랜잭션이 TransactionFlowOptions.Required 구성으로 흐르지 않으면 예외가 발생합니다.)

+0

굉장합니다. NetTCP 바인딩을 프로그래밍 방식으로 만들고 바인딩을 설정하지 않았습니다 .TransactionFlow = true -이 작업을 수행하면 예상대로 작동합니다. 고마워. –

관련 문제