Nun*_*res 8 wcf transactionscope tridion
我写了一个类来帮助使用核心服务向目标添加和删除目标.目标通常通过核心服务公开为一个字符串(带有XML内容),所以我写了我自己的包装器,等等.
我现在有一种情况需要更新2个发布目标,并认为使用事务范围确保两个目标同时更新会很酷.
然而,我正在努力实现这一点.
代码工作(使用标准CoreService WCF客户端):
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();
}
Run Code Online (Sandbox Code Playgroud)
执行此代码将成功回滚我所做的更改(如果我之前中断scope.Dispose()并检查Tridion中的发布目标,它成功更改目标,然后"撤消"更改).
如果我现在也尝试在交易中使用我的"扩展出版物目标"类,我无法处理它.
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();
}
Run Code Online (Sandbox Code Playgroud)
所以基本上,这就是问题:我必须做些什么来为我的.Save()方法添加事务性?
我试过这样做:
[OperationContract]
[TransactionFlow(TransactionFlowOption.Allowed)]
public void Save()
{
_client.Save(targetData, readOptions);
}
Run Code Online (Sandbox Code Playgroud)
但它并没有什么不同.有没有办法确定我目前是否在交易中并以某种方式"使用"该交易?我不想要一个交易,只想拥有一个操作选项.
谢谢,抱歉很长的帖子...想确保我提供尽可能多的信息.
最好的资源是:WCF Transaction Propagation
\n\n你至少错过了一步。您还需要在绑定中启用事务:
\n\n<bindings>\n <netTcpBinding>\n <binding name = \xe2\x80\x9cTransactionalTCP\xe2\x80\x9d transactionFlow = \xe2\x80\x9ctrue\xe2\x80\x9d />\n </netTcpBinding>\n</bindings>\nRun Code Online (Sandbox Code Playgroud)\n\n\n\n\n有没有办法确定我当前是否处于交易中并\n以某种方式“使用”该交易?
\n
是的。要确定您是否处于交易中,您可以检查 Transaction.Current。如果您正在进行交易,除非您明确选择退出,否则您将使用它。这就是环境交易的美丽/可怕之处。
\n\nWCF 事务传播中的图 5 :
\n\nclass MyService : IMyContract \n{\n [OperationBehavior(TransactionScopeRequired = true)] \n public void MyMethod(...)\n {\n Transaction transaction = Transaction.Current;\n Debug.Assert(transaction.TransactionInformation.\n DistributedIdentifier != Guid.Empty);\n } \n}\nRun Code Online (Sandbox Code Playgroud)\n\n如果 Transaction.Current.TransactionInformation.DistributedIdentifier 为空,则事务是本地的并且没有“流动”。请注意,在TransactionFlowOptions.Allowed配置中,如果事务无法流动,它会默默地失败。所以这确实是检查的唯一方法......并且不流动的情况比您想象的更容易发生。
当我将事务用于生产服务时,我实际上避免了TransactionFlowOptions.Allowed,因为调用者永远不确定事务是否真正流动。如果部署中存在绑定配置错误,一切都会运行良好,但回滚会失败......这是一个非常容易检测到的错误。所以我切换到必需的。然后调用者可以确保他们提供的交易实际上已成功传递。(如果事务未在 TransactionFlowOptions.Required配置中流动,您将收到异常。)