I wrote a class to assist in adding & removing Destinations to a Publication Target using the Core Service. Destinations are normally exposed as a string (with XML content) via the Core Service, so I wrote my own wrappers around that, etc.
I now have a situation where I need to update 2 publication targets and thought it would be cool to use a transaction scope to ensure that both targets are updated at the same time.
I am however struggling with implementing this.
Code working (using standard CoreService WCF client):
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();
}
Executing this code will successfully roll back the changes I did (if I break before scope.Dispose()
and check the publication targets in Tridion it successfully changes the target, and then "undoes" the change).
If I now try to use my "extended Publication Target" class also in a Transaction, I can't dispose it.
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();
}
So basically, this is the question: What must I do to add transactionality to my .Save() method?
I have tried doing this:
[OperationContract]
[TransactionFlow(TransactionFlowOption.Allowed)]
public void Save()
{
_client.Save(targetData, readOptions);
}
But it didn't make a difference. Is there a way to determine if I am currently in a transaction and somehow "use" that transaction? I don't want to require a transaction, just want to have the option to operate in one.
Thanks, and sorry for the very long post... wanted to make sure I provided as much info as possible.