如何使用CoreService在自定义类上实现WCF事务支持?

如何使用CoreService在自定义类上实现WCF事务支持?,wcf,tridion,transactionscope,Wcf,Tridion,Transactionscope,我编写了一个类来帮助使用核心服务向发布目标添加和删除目标。目的地通常通过核心服务以字符串(包含XML内容)的形式公开,因此我编写了自己的包装,等等 我现在遇到了一个需要更新2个发布目标的情况,我认为使用事务作用域来确保两个目标同时更新会很酷 然而,我正在努力实现这一点 代码工作(使用标准CoreService WCF客户端): TransactionOptions txOptions=新的TransactionOptions {IsolationLevel=IsolationLevel.Read

我编写了一个类来帮助使用核心服务向发布目标添加和删除目标。目的地通常通过核心服务以字符串(包含XML内容)的形式公开,因此我编写了自己的包装,等等

我现在遇到了一个需要更新2个发布目标的情况,我认为使用事务作用域来确保两个目标同时更新会很酷

然而,我正在努力实现这一点

代码工作(使用标准CoreService WCF客户端):

TransactionOptions txOptions=新的TransactionOptions
{IsolationLevel=IsolationLevel.ReadCommitted};
使用(TransactionScope范围=新TransactionScope(
TransactionScopeOption.必选,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);
//停止储蓄
scope.Dispose();
}
执行此代码将成功回滚我所做的更改(如果我在
scope.Dispose()
之前中断并检查Tridion中的发布目标,则会成功更改目标,然后“撤消”更改)

如果我现在还试图在事务中使用我的“扩展发布目标”类,我将无法处理它

TransactionOptions=new TransactionOptions{IsolationLevel=IsolationLevel.ReadCommitted};
使用(TransactionScope范围=新TransactionScope(TransactionScopeOption.Required,options))
{
ExtendedPublicationTarget1=新的ExtendedPublicationTarget(“tcm:0-1-65537”);
ExtendedPublicationTarget2=新的ExtendedPublicationTarget(“tcm:0-2-65537”);
target1.Destinations.Add(target1.Destinations[0]);
target2.Destinations.Add(target2.Destinations[0]);
target1.Save();
target2.Save();
scope.Dispose();
}
所以基本上,这就是问题:我必须做什么才能将事务性添加到.Save()方法中

我尝试过这样做:

[运营合同]
[TransactionFlow(TransactionFlowOption.Allowed)]
公共作废保存()
{
_保存(targetData,readOptions);
}
但这没什么区别。是否有办法确定我当前是否在某个事务中,并以某种方式“使用”该事务?我不想要求交易,只想选择在一个交易中操作


谢谢,很抱歉发了这么长的帖子。。。希望确保我提供了尽可能多的信息。

最好的资源是:

您至少错过了一步。您还需要在绑定中启用事务:

<bindings>
   <netTcpBinding>
      <binding name = “TransactionalTCP” transactionFlow = “true” />
   </netTcpBinding>
</bindings>
如果Transaction.Current.TransactionInformation.DistributeIdentifier为空,则该事务是本地事务,并且没有“流动”。请注意,在
TransactionFlowOptions.Allowed
配置中,如果事务无法流动,它将以静默方式失败。所以这真的是唯一的方法来检查。。。不流动的发生比你想象的要容易


当我为生产服务使用Transactions时,我实际上避免了
TransactionFlowOptions.Allowed
,因为调用者从不确定事务是否实际流动。如果部署中存在绑定配置错误,则一切都会正常运行,但回滚将失败。。。一个很容易被发现的错误。所以我改成了必修课。然后调用方可以确保他们提供的事务实际上已成功传递。(如果事务未在
TransactionFlowOptions.Required
配置中流动,则会出现异常。)

由于在
using
子句中有
scope
变量,因此不应显式调用
Dispose
。相反,它将在
using
块结束时自动处理。您可以说“我不能使用它”。这是什么意思?你有编译器错误吗?例外?或者代码只是不更新您的目标?(注:如果WCF事务是按照我习惯的方式命名的,TransactionScope将“背驮”现有事务或启动新事务。但由于我没有WCF事务的经验,我更希望看到其他人确认/纠正该假设)。嘿,Frank,我正试图让它失败,因此我调用了scope.Dispose()。在第一个例子中,它正确地失败了,而在第二个例子中,它没有。我只是想弄清楚我需要在课堂上添加什么才能让它发挥作用……太棒了。我以编程方式创建了NetTCP绑定,但没有将binding.TransactionFlow=true设置为-完成此操作后,一切正常。谢谢
class MyService : IMyContract 
{
   [OperationBehavior(TransactionScopeRequired = true)]   
   public void MyMethod(...)
   {
      Transaction transaction = Transaction.Current;
      Debug.Assert(transaction.TransactionInformation.
                   DistributedIdentifier != Guid.Empty);
   } 
}